/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.policy.impl;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;

/**
 * A vertical linear layout.  However, instead of drawing the background
 * behnd the items, it draws the background outside the items based on the
 * padding.  If there isn't enough room to draw both, it clips the background
 * instead of the contents.
 */
public class RecentApplicationsBackground extends LinearLayout {
    private static final String TAG = "RecentApplicationsBackground";

    private boolean mBackgroundSizeChanged;
    private Drawable mBackground;
    private Rect mTmp0 = new Rect();
    private Rect mTmp1 = new Rect();

    public RecentApplicationsBackground(Context context) {
        this(context, null);
        init();
    }

    public RecentApplicationsBackground(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mBackground = getBackground();
        setBackgroundDrawable(null);
        setPadding(0, 0, 0, 0);
        setGravity(Gravity.CENTER);
    }

    @Override
    protected boolean setFrame(int left, int top, int right, int bottom) {
        setWillNotDraw(false);
        if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
            mBackgroundSizeChanged = true;
        }
        return super.setFrame(left, top, right, bottom);
    }

    @Override
    protected boolean verifyDrawable(Drawable who) {
        return who == mBackground || super.verifyDrawable(who);
    }

    @Override
    public void jumpDrawablesToCurrentState() {
        super.jumpDrawablesToCurrentState();
        if (mBackground != null) mBackground.jumpToCurrentState();
    }

    @Override
    protected void drawableStateChanged() {
        Drawable d = mBackground;
        if (d != null && d.isStateful()) {
            d.setState(getDrawableState());
        }
        super.drawableStateChanged();
    }

    @Override
    public void draw(Canvas canvas) {
        final Drawable background = mBackground;
        if (background != null) {
            if (mBackgroundSizeChanged) {
                mBackgroundSizeChanged = false;
                Rect chld = mTmp0;
                Rect bkg = mTmp1;
                mBackground.getPadding(bkg);
                getChildBounds(chld);
                // This doesn't clamp to this view's bounds, which is what we want,
                // so that the drawing is clipped.
                final int top = chld.top - bkg.top;
                final int bottom = chld.bottom + bkg.bottom;
                // The background here is a gradient that wants to
                // extend the full width of the screen (whatever that
                // may be).
                int left, right;
                if (false) {
                    // This limits the width of the drawable.
                    left = chld.left - bkg.left;
                    right = chld.right + bkg.right;
                } else {
                    // This expands it to full width.
                    left = 0;
                    right = getRight();
                }
                background.setBounds(left, top, right, bottom);
            }
        }
        mBackground.draw(canvas);

        if (false) {
            android.graphics.Paint p = new android.graphics.Paint();
            p.setColor(0x88ffff00);
            canvas.drawRect(background.getBounds(), p);
        }
        canvas.drawARGB((int)(0.75*0xff), 0, 0, 0);

        super.draw(canvas);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        mBackground.setCallback(this);
        setWillNotDraw(false);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mBackground.setCallback(null);
    }
    
    private void getChildBounds(Rect r) {
        r.left = r.top = Integer.MAX_VALUE;
        r.bottom = r.right = Integer.MIN_VALUE;
        final int N = getChildCount();
        for (int i=0; i<N; i++) {
            View v = getChildAt(i);
            if (v.getVisibility() == View.VISIBLE) {
                r.left = Math.min(r.left, v.getLeft());
                r.top = Math.min(r.top, v.getTop());
                r.right = Math.max(r.right, v.getRight());
                r.bottom = Math.max(r.bottom, v.getBottom());
            }
        }
    }
}
