/*
 * Copyright (C) 2011 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 com.android.camera.R;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;

// This is an indicator button and pressing it opens a popup window. Ex: flash or other settings.
public abstract class AbstractIndicatorButton extends RotateImageView implements
        PopupManager.OnOtherPopupShowedListener {
    private final String TAG = "AbstractIndicatorButton";
    protected Animation mFadeIn, mFadeOut;
    protected final int HIGHLIGHT_COLOR;
    protected AbstractSettingPopup mPopup;
    protected Handler mHandler = new MainHandler();
    private final int MSG_DISMISS_POPUP = 0;
    private IndicatorChangeListener mListener;


    public static interface IndicatorChangeListener {
        public void onShowIndicator(View view, boolean showed);
    }

    public AbstractIndicatorButton(Context context) {
        super(context);
        mFadeIn = AnimationUtils.loadAnimation(context, R.anim.grow_fade_in_from_right);
        mFadeOut = AnimationUtils.loadAnimation(context, R.anim.shrink_fade_out_from_right);
        HIGHLIGHT_COLOR = context.getResources().getColor(R.color.review_control_pressed_color);
        setScaleType(ImageView.ScaleType.CENTER);
        PopupManager.getInstance(context).setOnOtherPopupShowedListener(this);
        // Set the click listener to help the comprehension of the accessibility.
        setClickable(true);
    }

    @Override
    public void onOtherPopupShowed() {
        dismissPopup();
    }

    public void setIndicatorChangeListener(IndicatorChangeListener listener) {
        mListener = listener;
    }

    // Whether scene mode affects this indicator and it cannot be changed.
    public boolean isOverridden() {
        return false;
    }

    // Scene mode may override other settings like flash, white-balance, and focus.
    abstract public void overrideSettings(final String ... keyvalues);

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (!isEnabled()) return false;

        int action = ev.getAction();
        if (action == MotionEvent.ACTION_DOWN && !isOverridden()) {
            if (mPopup == null || mPopup.getVisibility() != View.VISIBLE) {
                showPopup();
                PopupManager.getInstance(getContext()).notifyShowPopup(this);
            } else {
                dismissPopup();
            }
            return true;
        } else if (action == MotionEvent.ACTION_CANCEL) {
            dismissPopup();
            return true;
        }
        return false;
    }

    @Override
    public void setEnabled(boolean enabled) {
        // Do not enable the button if it is overridden by scene mode.
        if (isOverridden()) {
            enabled = false;
        }

        // Don't do anything if state is not changed so not to interfere with
        // the "highlight" state.
        if (isEnabled() ^ enabled) {
            super.setEnabled(enabled);
        }
    }

    @Override
    public void setDegree(int degree) {
        super.setDegree(degree);
        if (mPopup != null) {
            mPopup.setOrientation(degree);
        }
    }

    abstract protected void initializePopup();

    private void showPopup() {
        mHandler.removeMessages(MSG_DISMISS_POPUP);
        if (mPopup == null) initializePopup();

        mPopup.setVisibility(View.VISIBLE);
        mPopup.setOrientation(getDegree());
        mPopup.clearAnimation();
        mPopup.startAnimation(mFadeIn);
        if (mListener != null) mListener.onShowIndicator(this, true);
    }

    public boolean dismissPopup() {
        mHandler.removeMessages(MSG_DISMISS_POPUP);
        if (mPopup != null && mPopup.getVisibility() == View.VISIBLE) {
            mPopup.clearAnimation();
            mPopup.startAnimation(mFadeOut);
            mPopup.setVisibility(View.GONE);
            if (mListener != null) mListener.onShowIndicator(this, false);
            invalidate();
            // Indicator wheel needs to update the highlight indicator if this
            // is dismissed by MSG_DISMISS_POPUP.
            ((View) getParent()).invalidate();
            return true;
        }
        return false;
    }

    public AbstractSettingPopup getPopupWindow() {
        if (mPopup != null && mPopup.getVisibility() == View.VISIBLE) {
            return mPopup;
        } else {
            return null;
        }
    }

    public void reloadPreference() {
        if (mPopup != null) mPopup.reloadPreference();
    }

    protected void dismissPopupDelayed() {
        if (!mHandler.hasMessages(MSG_DISMISS_POPUP)) {
            mHandler.sendEmptyMessage(MSG_DISMISS_POPUP);
        }
    }

    private class MainHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_DISMISS_POPUP:
                    dismissPopup();
                    break;
            }
        }
    }
}
