/*
 * 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.camera.ui;

import com.android.camera.IconListPreference;
import com.android.camera.PreferenceGroup;
import com.android.camera.R;
import com.android.camera.Util;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

/**
 * A view that contains camera setting indicators which are spread over a
 * vertical bar in preview frame.
 */
public class SecondLevelIndicatorControlBar extends IndicatorControl implements
        View.OnClickListener, AbstractIndicatorButton.IndicatorChangeListener {
    private static final String TAG = "SecondLevelIndicatorControlBar";
    private static int ICON_SPACING = Util.dpToPixel(16);
    private View mCloseIcon;
    private View mDivider; // the divider line
    private View mIndicatorHighlight; // the side highlight bar
    private View mPopupedIndicator;
    int mOrientation = 0;
    int mSelectedIndex = -1;
    // There are some views in the ViewGroup before adding the indicator buttons,
    // such as Close icon, divider line and the hightlight bar, we need to
    // remember the count of the non-indicator buttons for getTouchViewIndex().
    int mNonIndicatorButtonCount;

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

    @Override
    protected void onFinishInflate() {
        mDivider = findViewById(R.id.divider);
        mIndicatorHighlight = findViewById(R.id.indicator_highlight);
        mCloseIcon = findViewById(R.id.back_to_first_level);
        mCloseIcon.setOnClickListener(this);
    }

    public void initialize(Context context, PreferenceGroup group,
            String[] keys, String[] otherSettingKeys) {

        setPreferenceGroup(group);
        mNonIndicatorButtonCount = getChildCount();
        addControls(keys, otherSettingKeys);
        if (mOrientation != 0) setOrientation(mOrientation);
    }

    public void onClick(View view) {
        dismissSettingPopup();
        mOnIndicatorEventListener.onIndicatorEvent(
                    OnIndicatorEventListener.EVENT_LEAVE_SECOND_LEVEL_INDICATOR_BAR);
    }

    private int getTouchViewIndex(int x, int width) {
        // If the current touch location is on close icon and above.
        if (x > mCloseIcon.getLeft()) return indexOfChild(mCloseIcon);

        // Calculate if the touch event is on the indicator buttons.
        int count = getChildCount();
        if (count == mNonIndicatorButtonCount) return -1;
        // The baseline will be the first indicator button's top minus spacing.
        View firstIndicatorButton = getChildAt(mNonIndicatorButtonCount);
        int baselineX = firstIndicatorButton.getRight() + (ICON_SPACING / 2);
        if (x > baselineX) return -1;
        int iconWidth = firstIndicatorButton.getMeasuredWidth();
        int buttonRange = iconWidth + ICON_SPACING;
        return (mNonIndicatorButtonCount + ((baselineX - x) / buttonRange));
    }

    private void dispatchRelativeTouchEvent(View view, MotionEvent event) {
        event.offsetLocation(-view.getLeft(), -view.getTop());
        view.dispatchTouchEvent(event);
        event.offsetLocation(view.getLeft(), view.getTop());
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        if (!onFilterTouchEventForSecurity(event)) return false;

        int action = event.getAction();
        if (!isEnabled()) return false;

        double x = (double) event.getX();
        double y = (double) event.getY();
        int width = getWidth();
        if (width == 0) return false; // the event is sent before onMeasure()
        if (x > width) x = width;
        if (y >= getHeight()) y = getHeight() - 1;

        int index = getTouchViewIndex((int) x, width);
        if (index == -1) return true;
        View b = getChildAt(index);
        dispatchRelativeTouchEvent(b, event);
        if ((mSelectedIndex != -1) && (index != mSelectedIndex)) {
            View v = getChildAt(mSelectedIndex);
            if (v instanceof AbstractIndicatorButton) {
                AbstractIndicatorButton c = (AbstractIndicatorButton) v;
                event.setAction(MotionEvent.ACTION_CANCEL);
                dispatchRelativeTouchEvent(c, event);
                c.dismissPopup();
            }

            if (action == MotionEvent.ACTION_MOVE) {
                event.setAction(MotionEvent.ACTION_DOWN);
                dispatchRelativeTouchEvent(b, event);
            }
        }
        mSelectedIndex = index;
        return true;
    }

    @Override
    public IndicatorButton addIndicator(Context context, IconListPreference pref) {
        IndicatorButton b = super.addIndicator(context, pref);
        b.setIndicatorChangeListener(this);
        return b;
    }

    @Override
    public OtherSettingIndicatorButton addOtherSettingIndicator(Context context,
            int resId, String[] keys) {
        OtherSettingIndicatorButton b =
                super.addOtherSettingIndicator(context, resId, keys);
        b.setIndicatorChangeListener(this);
        return b;
    }

    @Override
    public void onShowIndicator(View view, boolean showed) {
        // Ignore those events if not current popup.
        if (!showed && (mPopupedIndicator != view)) return;
        mPopupedIndicator = (showed ? view : null);
        // Show or dismiss the side indicator highlight.
        requestLayout();
    }

    @Override
    public void setOrientation(int orientation) {
        mOrientation = orientation;
        super.setOrientation(orientation);
    }

    @Override
    protected void onLayout(
            boolean changed, int left, int top, int right, int bottom) {
        int count = getChildCount();
        if (count == 0) return;
        int width = right - left;
        int height = bottom - top;
        int iconWidth = mCloseIcon.getMeasuredWidth();
        int padding = getPaddingLeft();

        // Layout from the last icon up.
        int offsetX = padding;
        int increment = iconWidth + ICON_SPACING;
        for (int i = count - 1; i >= mNonIndicatorButtonCount; --i) {
            getChildAt(i).layout(offsetX, 0, offsetX + iconWidth, height);
            offsetX += increment;
        }

        // And layout the divider line.
        offsetX = width - iconWidth - 2 * padding;
        mDivider.layout(offsetX, padding, (offsetX + mDivider.getMeasuredWidth()),
                (height - padding));

        offsetX = width - iconWidth - padding;
        // The first icon is close button.
        mCloseIcon.layout(offsetX, 0, (offsetX + iconWidth), height);

        // Hightlight the selected indicator if exists.
        if (mPopupedIndicator == null) {
            mIndicatorHighlight.setVisibility(View.GONE);
        } else {
            mIndicatorHighlight.setVisibility(View.VISIBLE);
            // Keep the top and bottom of the hightlight the same as
            // the 'active' indicator button.
            mIndicatorHighlight.layout(mPopupedIndicator.getLeft(), 0,
                    mPopupedIndicator.getRight(),
                    mIndicatorHighlight.getLayoutParams().height);
        }
   }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        if (mCurrentMode == MODE_VIDEO) {
            mCloseIcon.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
        }
        mCloseIcon.setEnabled(enabled);
    }
}
