/*
 * 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.CameraPreference.OnPreferenceChangedListener;
import com.android.camera.IconListPreference;
import com.android.camera.ListPreference;
import com.android.camera.PreferenceGroup;
import com.android.camera.CameraSettings;
import com.android.camera.R;

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

import java.util.ArrayList;

/**
 * A view that contains camera setting indicators.
 */
public abstract class IndicatorControl extends RelativeLayout implements
        IndicatorButton.Listener, OtherSettingsPopup.Listener, Rotatable {
    private static final String TAG = "IndicatorControl";
    public static final int MODE_CAMERA = 0;
    public static final int MODE_VIDEO = 1;

    private OnPreferenceChangedListener mListener;
    protected OnIndicatorEventListener mOnIndicatorEventListener;
    protected CameraPicker mCameraPicker;

    private PreferenceGroup mPreferenceGroup;
    private int mOrientation = 0;

    protected int mCurrentMode = MODE_CAMERA;

    ArrayList<AbstractIndicatorButton> mIndicators =
            new ArrayList<AbstractIndicatorButton>();

    public void setListener(OnPreferenceChangedListener listener) {
        mListener = listener;
        if (mCameraPicker != null) mCameraPicker.setListener(listener);
    }

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

    public void setOrientation(int orientation) {
        mOrientation = orientation;
        int count = getChildCount();
        for (int i = 0 ; i < count ; ++i) {
            View view = getChildAt(i);
            if (view instanceof Rotatable) {
                ((Rotatable) view).setOrientation(orientation);
            }
        }
    }

    public void setOnIndicatorEventListener(OnIndicatorEventListener listener) {
        mOnIndicatorEventListener = listener;
    }

    public void setPreferenceGroup(PreferenceGroup group) {
        mPreferenceGroup = group;
        // Preset the current mode from the title of preference group.
        String title = group.getTitle();
        if (title.equals(getContext().getString(
                R.string.pref_camcorder_settings_category))) {
            mCurrentMode = MODE_VIDEO;
        }
    }

    protected void addControls(String[] keys, String[] otherSettingKeys) {
        if (keys != null) {
            for (int i = 0; i < keys.length; i++) {
                IconListPreference pref =
                        (IconListPreference) mPreferenceGroup.findPreference(keys[i]);
                if (pref != null) {
                    addIndicator(getContext(), pref);
                }
            }
        }

        // Add other settings indicator.
        if (otherSettingKeys != null) {
            addOtherSettingIndicator(getContext(),
                    R.drawable.ic_menu_overflow, otherSettingKeys);
        }
    }

    protected void initializeCameraPicker() {
        ListPreference pref = mPreferenceGroup.findPreference(
                CameraSettings.KEY_CAMERA_ID);
        if (pref == null) return;
        mCameraPicker = new CameraPicker(getContext());
        mCameraPicker.initialize(pref);
        addView(mCameraPicker);
    }

    @Override
    public boolean shouldDelayChildPressedState() {
        // Return false so the pressed feedback of the back/front camera switch
        // can be showed right away.
        return false;
    }

    public IndicatorButton addIndicator(Context context, IconListPreference pref) {
        IndicatorButton b = new IndicatorButton(context, pref);
        b.setSettingChangedListener(this);
        b.setContentDescription(pref.getTitle());
        addView(b);
        mIndicators.add(b);
        return b;
    }

    public OtherSettingIndicatorButton addOtherSettingIndicator(Context context,
            int resId, String[] keys) {
        OtherSettingIndicatorButton b = new OtherSettingIndicatorButton(
                context, resId, mPreferenceGroup, keys);
        b.setSettingChangedListener(this);
        b.setContentDescription(getResources().getString(
                R.string.pref_camera_settings_category));
        addView(b);
        mIndicators.add(b);
        return b;
    }

    @Override
    public void onRestorePreferencesClicked() {
        if (mListener != null) {
            mListener.onRestorePreferencesClicked();
        }
    }

    @Override
    public void onSettingChanged() {
        if (mListener != null) {
            mListener.onSharedPreferenceChanged();
        }
    }

    public boolean dismissSettingPopup() {
        for (AbstractIndicatorButton v: mIndicators) {
            if (v.dismissPopup()) {
                invalidate();
                return true;
            }
        }
        return false;
    }

    public View getActiveSettingPopup() {
        for (AbstractIndicatorButton v: mIndicators) {
            View result = v.getPopupWindow();
            if (result != null) return result;
        }
        return null;
    }

    // Scene mode may override other camera settings (ex: flash mode).
    public void overrideSettings(final String ... keyvalues) {
        if (keyvalues.length % 2 != 0) {
            throw new IllegalArgumentException();
        }

        for (AbstractIndicatorButton b: mIndicators) {
            b.overrideSettings(keyvalues);
        }
    }

    public void reloadPreferences() {
        mPreferenceGroup.reloadValue();
        for (AbstractIndicatorButton b: mIndicators) {
            b.reloadPreference();
        }
    }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View v = getChildAt(i);
            // Zoom buttons and shutter button are controlled by the activity.
            if (v instanceof AbstractIndicatorButton) {
                v.setEnabled(enabled);
                // Show or hide the indicator buttons during recording.
                if (mCurrentMode == MODE_VIDEO) {
                    v.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
                }
            }
        }
        if (mCameraPicker != null) {
            mCameraPicker.setEnabled(enabled);
            if (mCurrentMode == MODE_VIDEO) {
                mCameraPicker.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
            }
        }
    }
}