/*
 * Copyright (C) 2013 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.camera.ui;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.TransitionDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageButton;

import com.android.camera.CaptureLayoutHelper;
import com.android.camera.ShutterButton;
import com.android.camera.debug.Log;
import com.android.camera.util.ApiHelper;
import com.android.camera.util.CameraUtil;
import com.android.camera2.R;

/**
 * BottomBar swaps its width and height on rotation. In addition, it also
 * changes gravity and layout orientation based on the new orientation.
 * Specifically, in landscape it aligns to the right side of its parent and lays
 * out its children vertically, whereas in portrait, it stays at the bottom of
 * the parent and has a horizontal layout orientation.
 */
public class BottomBar extends FrameLayout {

    private static final Log.Tag TAG = new Log.Tag("BottomBar");

    private static final int CIRCLE_ANIM_DURATION_MS = 300;
    private static final int DRAWABLE_MAX_LEVEL = 10000;
    private static final int MODE_CAPTURE = 0;
    private static final int MODE_INTENT = 1;
    private static final int MODE_INTENT_REVIEW = 2;
    private static final int MODE_CANCEL = 3;

    private int mMode;

    private final int mBackgroundAlphaOverlay;
    private final int mBackgroundAlphaDefault;
    private boolean mOverLayBottomBar;

    private FrameLayout mCaptureLayout;
    private FrameLayout mCancelLayout;
    private TopRightWeightedLayout mIntentReviewLayout;

    private ShutterButton mShutterButton;
    private ImageButton mCancelButton;

    private int mBackgroundColor;
    private int mBackgroundPressedColor;
    private int mBackgroundAlpha = 0xff;

    private boolean mDrawCircle;
    private final float mCircleRadius;
    private CaptureLayoutHelper mCaptureLayoutHelper = null;

    // for Android L, these backgrounds are RippleDrawables (ISA LayerDrawable)
    // pre-L, they're plain old LayerDrawables
    private final LayerDrawable[] mShutterButtonBackgrounds;
    // a reference to the shutter background's first contained drawable
    // if it's an animated circle drawable (for video mode)
    private AnimatedCircleDrawable mAnimatedCircleDrawable;
    // a reference to the shutter background's first contained drawable
    // if it's a color drawable (for all other modes)
    private ColorDrawable mColorDrawable;

    private RectF mRect = new RectF();

    public BottomBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        mCircleRadius = getResources()
                .getDimensionPixelSize(R.dimen.video_capture_circle_diameter) / 2;
        mBackgroundAlphaOverlay = getResources()
                .getInteger(R.integer.bottom_bar_background_alpha_overlay);
        mBackgroundAlphaDefault = getResources()
                .getInteger(R.integer.bottom_bar_background_alpha);

        // preload all the drawable BGs
        TypedArray ar = context.getResources()
                .obtainTypedArray(R.array.shutter_button_backgrounds);
        int len = ar.length();

        mShutterButtonBackgrounds = new LayerDrawable[len];
        for (int i = 0; i < len; i++) {
            int drawableId = ar.getResourceId(i, -1);
            LayerDrawable shutterBackground = mShutterButtonBackgrounds[i] =
                    (LayerDrawable) context.getResources().getDrawable(drawableId).mutate();

            // the background for video has a circle_item drawable placeholder
            // that gets replaced by an AnimatedCircleDrawable for the cool
            // shrink-down-to-a-circle effect
            // all other modes need not do this replace
            Drawable d = shutterBackground.findDrawableByLayerId(R.id.circle_item);
            if (d != null) {
                Drawable animatedCircleDrawable =
                        new AnimatedCircleDrawable((int) mCircleRadius);
                animatedCircleDrawable.setLevel(DRAWABLE_MAX_LEVEL);
                shutterBackground
                        .setDrawableByLayerId(R.id.circle_item, animatedCircleDrawable);
            }
        }
        ar.recycle();
    }

    private void setPaintColor(int alpha, int color) {
        if (mAnimatedCircleDrawable != null) {
            mAnimatedCircleDrawable.setColor(color);
            mAnimatedCircleDrawable.setAlpha(alpha);
        } else if (mColorDrawable != null) {
            mColorDrawable.setColor(color);
            mColorDrawable.setAlpha(alpha);
        }

        if (mIntentReviewLayout != null) {
            ColorDrawable intentBackground = (ColorDrawable) mIntentReviewLayout
                    .getBackground();
            intentBackground.setColor(color);
            intentBackground.setAlpha(alpha);
        }
    }

    private void refreshPaintColor() {
        setPaintColor(mBackgroundAlpha, mBackgroundColor);
    }

    private void setCancelBackgroundColor(int alpha, int color) {
        LayerDrawable layerDrawable = (LayerDrawable) mCancelButton.getBackground();
        ColorDrawable colorDrawable = (ColorDrawable) layerDrawable.getDrawable(0);
        if (!ApiHelper.isLOrHigher()) {
            colorDrawable.setColor(color);
        }
        colorDrawable.setAlpha(alpha);
    }

    private void setCaptureButtonUp() {
        setPaintColor(mBackgroundAlpha, mBackgroundColor);
    }

    private void setCaptureButtonDown() {
        if (!ApiHelper.isLOrHigher()) {
            setPaintColor(mBackgroundAlpha, mBackgroundPressedColor);
        }
    }

    private void setCancelButtonUp() {
        setCancelBackgroundColor(mBackgroundAlpha, mBackgroundColor);
    }

    private void setCancelButtonDown() {
        setCancelBackgroundColor(mBackgroundAlpha, mBackgroundPressedColor);
    }

    @Override
    public void onFinishInflate() {
        mCaptureLayout =
                (FrameLayout) findViewById(R.id.bottombar_capture);
        mCancelLayout =
                (FrameLayout) findViewById(R.id.bottombar_cancel);
        mCancelLayout.setVisibility(View.GONE);

        mIntentReviewLayout =
                (TopRightWeightedLayout) findViewById(R.id.bottombar_intent_review);

        mShutterButton =
                (ShutterButton) findViewById(R.id.shutter_button);
        mShutterButton.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (MotionEvent.ACTION_DOWN == event.getActionMasked()) {
                    setCaptureButtonDown();
                } else if (MotionEvent.ACTION_UP == event.getActionMasked() ||
                        MotionEvent.ACTION_CANCEL == event.getActionMasked()) {
                    setCaptureButtonUp();
                } else if (MotionEvent.ACTION_MOVE == event.getActionMasked()) {
                    mRect.set(0, 0, getWidth(), getHeight());
                    if (!mRect.contains(event.getX(), event.getY())) {
                        setCaptureButtonUp();
                    }
                }
                return false;
            }
        });

        mCancelButton =
                (ImageButton) findViewById(R.id.shutter_cancel_button);
        mCancelButton.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (MotionEvent.ACTION_DOWN == event.getActionMasked()) {
                    setCancelButtonDown();
                } else if (MotionEvent.ACTION_UP == event.getActionMasked() ||
                        MotionEvent.ACTION_CANCEL == event.getActionMasked()) {
                    setCancelButtonUp();
                } else if (MotionEvent.ACTION_MOVE == event.getActionMasked()) {
                    mRect.set(0, 0, getWidth(), getHeight());
                    if (!mRect.contains(event.getX(), event.getY())) {
                        setCancelButtonUp();
                    }
                }
                return false;
            }
        });

    }

    /**
     * Perform a transition from the bottom bar options layout to the bottom bar
     * capture layout.
     */
    public void transitionToCapture() {
        mCaptureLayout.setVisibility(View.VISIBLE);
        mCancelLayout.setVisibility(View.GONE);
        mIntentReviewLayout.setVisibility(View.GONE);

        mMode = MODE_CAPTURE;
    }

    /**
     * Perform a transition from the bottom bar options layout to the bottom bar
     * capture layout.
     */
    public void transitionToCancel() {
        mCaptureLayout.setVisibility(View.GONE);
        mIntentReviewLayout.setVisibility(View.GONE);
        mCancelLayout.setVisibility(View.VISIBLE);

        mMode = MODE_CANCEL;
    }

    /**
     * Perform a transition to the global intent layout. The current layout
     * state of the bottom bar is irrelevant.
     */
    public void transitionToIntentCaptureLayout() {
        mIntentReviewLayout.setVisibility(View.GONE);
        mCaptureLayout.setVisibility(View.VISIBLE);
        mCancelLayout.setVisibility(View.GONE);

        mMode = MODE_INTENT;
    }

    /**
     * Perform a transition to the global intent review layout. The current
     * layout state of the bottom bar is irrelevant.
     */
    public void transitionToIntentReviewLayout() {
        mCaptureLayout.setVisibility(View.GONE);
        mIntentReviewLayout.setVisibility(View.VISIBLE);
        mCancelLayout.setVisibility(View.GONE);

        mMode = MODE_INTENT_REVIEW;
    }

    /**
     * @return whether UI is in intent review mode
     */
    public boolean isInIntentReview() {
        return mMode == MODE_INTENT_REVIEW;
    }

    private void setButtonImageLevels(int level) {
        ((ImageButton) findViewById(R.id.cancel_button)).setImageLevel(level);
        ((ImageButton) findViewById(R.id.done_button)).setImageLevel(level);
        ((ImageButton) findViewById(R.id.retake_button)).setImageLevel(level);
    }

    private void setOverlayBottomBar(boolean overlay) {
        mOverLayBottomBar = overlay;
        if (overlay) {
            setBackgroundAlpha(mBackgroundAlphaOverlay);
            setButtonImageLevels(1);
        } else {
            setBackgroundAlpha(mBackgroundAlphaDefault);
            setButtonImageLevels(0);
        }
    }

    /**
     * Sets a capture layout helper to query layout rect from.
     */
    public void setCaptureLayoutHelper(CaptureLayoutHelper helper) {
        mCaptureLayoutHelper = helper;
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
        final int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
        if (measureWidth == 0 || measureHeight == 0) {
            return;
        }

        if (mCaptureLayoutHelper == null) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            Log.e(TAG, "Capture layout helper needs to be set first.");
        } else {
            RectF bottomBarRect = mCaptureLayoutHelper.getBottomBarRect();
            super.onMeasure(MeasureSpec.makeMeasureSpec(
                    (int) bottomBarRect.width(), MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec((int) bottomBarRect.height(), MeasureSpec.EXACTLY)
                    );
            boolean shouldOverlayBottomBar = mCaptureLayoutHelper.shouldOverlayBottomBar();
            setOverlayBottomBar(shouldOverlayBottomBar);
        }
    }

    // prevent touches on bottom bar (not its children)
    // from triggering a touch event on preview area
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return true;
    }

    @Override
    public void setBackgroundColor(int color) {
        mBackgroundColor = color;
        setPaintColor(mBackgroundAlpha, mBackgroundColor);
        setCancelBackgroundColor(mBackgroundAlpha, mBackgroundColor);
    }

    private void setBackgroundPressedColor(int color) {
        if (ApiHelper.isLOrHigher()) {
            // not supported (setting a color on a RippleDrawable is hard =[ )
        } else {
            mBackgroundPressedColor = color;
        }
    }

    private void setupShutterBackgroundForModeIndex(int index) {
        LayerDrawable shutterBackground = mShutterButtonBackgrounds[index];
        mShutterButton.setBackground(shutterBackground);

        Drawable d = shutterBackground.getDrawable(0);
        mAnimatedCircleDrawable = null;
        mColorDrawable = null;
        if (d instanceof AnimatedCircleDrawable) {
            mAnimatedCircleDrawable = (AnimatedCircleDrawable) d;
        } else if (d instanceof ColorDrawable) {
            mColorDrawable = (ColorDrawable) d;
        }

        int colorId = CameraUtil.getCameraThemeColorId(index, getContext());
        int pressedColor = getContext().getResources().getColor(colorId);
        setBackgroundPressedColor(pressedColor);
        refreshPaintColor();
    }

    public void setColorsForModeIndex(int index) {
        setupShutterBackgroundForModeIndex(index);
    }

    public void setBackgroundAlpha(int alpha) {
        mBackgroundAlpha = alpha;
        setPaintColor(mBackgroundAlpha, mBackgroundColor);
        setCancelBackgroundColor(mBackgroundAlpha, mBackgroundColor);
    }

    /**
     * Sets the shutter button enabled if true, disabled if false.
     * <p>
     * Disabled means that the shutter button is not clickable and is greyed
     * out.
     */
    public void setShutterButtonEnabled(final boolean enabled) {
        mShutterButton.post(new Runnable() {
            @Override
            public void run() {
                mShutterButton.setEnabled(enabled);
                setShutterButtonImportantToA11y(enabled);
            }
        });
    }

    /**
     * Sets whether shutter button should be included in a11y announcement and
     * navigation
     */
    public void setShutterButtonImportantToA11y(boolean important) {
        if (important) {
            mShutterButton.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
        } else {
            mShutterButton.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
        }
    }

    /**
     * Returns whether the capture button is enabled.
     */
    public boolean isShutterButtonEnabled() {
        return mShutterButton.isEnabled();
    }

    private TransitionDrawable crossfadeDrawable(Drawable from, Drawable to) {
        Drawable[] arrayDrawable = new Drawable[2];
        arrayDrawable[0] = from;
        arrayDrawable[1] = to;
        TransitionDrawable transitionDrawable = new TransitionDrawable(arrayDrawable);
        transitionDrawable.setCrossFadeEnabled(true);
        return transitionDrawable;
    }

    /**
     * Sets the shutter button's icon resource. By default, all drawables
     * instances loaded from the same resource share a common state; if you
     * modify the state of one instance, all the other instances will receive
     * the same modification. In order to modify properties of this icon
     * drawable without affecting other drawables, here we use a mutable
     * drawable which is guaranteed to not share states with other drawables.
     */
    public void setShutterButtonIcon(int resId) {
        Drawable iconDrawable = getResources().getDrawable(resId);
        if (iconDrawable != null) {
            iconDrawable = iconDrawable.mutate();
        }
        mShutterButton.setImageDrawable(iconDrawable);
    }

    /**
     * Animates bar to a single stop button
     */
    public void animateToVideoStop(int resId) {
        if (mOverLayBottomBar && mAnimatedCircleDrawable != null) {
            mAnimatedCircleDrawable.animateToSmallRadius();
            mDrawCircle = true;
        }

        TransitionDrawable transitionDrawable = crossfadeDrawable(
                mShutterButton.getDrawable(),
                getResources().getDrawable(resId));
        mShutterButton.setImageDrawable(transitionDrawable);
        transitionDrawable.startTransition(CIRCLE_ANIM_DURATION_MS);
    }

    /**
     * Animates bar to full width / length with video capture icon
     */
    public void animateToFullSize(int resId) {
        if (mDrawCircle && mAnimatedCircleDrawable != null) {
            mAnimatedCircleDrawable.animateToFullSize();
            mDrawCircle = false;
        }

        TransitionDrawable transitionDrawable = crossfadeDrawable(
                mShutterButton.getDrawable(),
                getResources().getDrawable(resId));
        mShutterButton.setImageDrawable(transitionDrawable);
        transitionDrawable.startTransition(CIRCLE_ANIM_DURATION_MS);
    }
}
