/*
 * 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 android.annotation.TargetApi;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.SimpleAdapter;

import com.android.camera.IconListPreference;

import com.android.gallery3d.R;
import com.android.gallery3d.common.ApiHelper;

import java.util.ArrayList;
import java.util.HashMap;

// A popup window that shows video effect setting. It has two grid view.
// One shows the goofy face effects. The other shows the background replacer
// effects.
public class EffectSettingPopup extends AbstractSettingPopup implements
        AdapterView.OnItemClickListener, View.OnClickListener {
    private static final String TAG = "EffectSettingPopup";
    private String mNoEffect;
    private IconListPreference mPreference;
    private Listener mListener;
    private View mClearEffects;
    private GridView mSillyFacesGrid;
    private GridView mBackgroundGrid;

    // Data for silly face items. (text, image, and preference value)
    ArrayList<HashMap<String, Object>> mSillyFacesItem =
            new ArrayList<HashMap<String, Object>>();

    // Data for background replacer items. (text, image, and preference value)
    ArrayList<HashMap<String, Object>> mBackgroundItem =
            new ArrayList<HashMap<String, Object>>();


    static public interface Listener {
        public void onSettingChanged();
    }

    public EffectSettingPopup(Context context, AttributeSet attrs) {
        super(context, attrs);
        mNoEffect = context.getString(R.string.pref_video_effect_default);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mClearEffects = findViewById(R.id.clear_effects);
        mClearEffects.setOnClickListener(this);
        mSillyFacesGrid = (GridView) findViewById(R.id.effect_silly_faces);
        mBackgroundGrid = (GridView) findViewById(R.id.effect_background);
    }

    public void initialize(IconListPreference preference) {
        mPreference = preference;
        Context context = getContext();
        CharSequence[] entries = mPreference.getEntries();
        CharSequence[] entryValues = mPreference.getEntryValues();
        int[] iconIds = mPreference.getImageIds();
        if (iconIds == null) {
            iconIds = mPreference.getLargeIconIds();
        }

        // Set title.
        mTitle.setText(mPreference.getTitle());

        for(int i = 0; i < entries.length; ++i) {
            String value = entryValues[i].toString();
            if (value.equals(mNoEffect)) continue;  // no effect, skip it.
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("value", value);
            map.put("text", entries[i].toString());
            if (iconIds != null) map.put("image", iconIds[i]);
            if (value.startsWith("goofy_face")) {
                mSillyFacesItem.add(map);
            } else if (value.startsWith("backdropper")) {
                mBackgroundItem.add(map);
            }
        }

        boolean hasSillyFaces = mSillyFacesItem.size() > 0;
        boolean hasBackground = mBackgroundItem.size() > 0;

        // Initialize goofy face if it is supported.
        if (hasSillyFaces) {
            findViewById(R.id.effect_silly_faces_title).setVisibility(View.VISIBLE);
            findViewById(R.id.effect_silly_faces_title_separator).setVisibility(View.VISIBLE);
            mSillyFacesGrid.setVisibility(View.VISIBLE);
            SimpleAdapter sillyFacesItemAdapter = new SimpleAdapter(context,
                    mSillyFacesItem, R.layout.effect_setting_item,
                    new String[] {"text", "image"},
                    new int[] {R.id.text, R.id.image});
            mSillyFacesGrid.setAdapter(sillyFacesItemAdapter);
            mSillyFacesGrid.setOnItemClickListener(this);
        }

        if (hasSillyFaces && hasBackground) {
            findViewById(R.id.effect_background_separator).setVisibility(View.VISIBLE);
        }

        // Initialize background replacer if it is supported.
        if (hasBackground) {
            findViewById(R.id.effect_background_title).setVisibility(View.VISIBLE);
            findViewById(R.id.effect_background_title_separator).setVisibility(View.VISIBLE);
            mBackgroundGrid.setVisibility(View.VISIBLE);
            SimpleAdapter backgroundItemAdapter = new SimpleAdapter(context,
                    mBackgroundItem, R.layout.effect_setting_item,
                    new String[] {"text", "image"},
                    new int[] {R.id.text, R.id.image});
            mBackgroundGrid.setAdapter(backgroundItemAdapter);
            mBackgroundGrid.setOnItemClickListener(this);
        }

        reloadPreference();
    }

    @Override
    public void setVisibility(int visibility) {
        if (visibility == View.VISIBLE) {
            if (getVisibility() != View.VISIBLE) {
                // Do not show or hide "Clear effects" button when the popup
                // is already visible. Otherwise it looks strange.
                boolean noEffect = mPreference.getValue().equals(mNoEffect);
                mClearEffects.setVisibility(noEffect ? View.GONE : View.VISIBLE);
            }
            reloadPreference();
        }
        super.setVisibility(visibility);
    }

    // The value of the preference may have changed. Update the UI.
    @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
    @Override
    public void reloadPreference() {
        mBackgroundGrid.setItemChecked(mBackgroundGrid.getCheckedItemPosition(), false);
        mSillyFacesGrid.setItemChecked(mSillyFacesGrid.getCheckedItemPosition(), false);

        String value = mPreference.getValue();
        if (value.equals(mNoEffect)) return;

        for (int i = 0; i < mSillyFacesItem.size(); i++) {
            if (value.equals(mSillyFacesItem.get(i).get("value"))) {
                mSillyFacesGrid.setItemChecked(i, true);
                return;
            }
        }

        for (int i = 0; i < mBackgroundItem.size(); i++) {
            if (value.equals(mBackgroundItem.get(i).get("value"))) {
                mBackgroundGrid.setItemChecked(i, true);
                return;
            }
        }

        Log.e(TAG, "Invalid preference value: " + value);
        mPreference.print();
    }

    public void setSettingChangedListener(Listener listener) {
        mListener = listener;
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view,
            int index, long id) {
        String value;
        if (parent == mSillyFacesGrid) {
            value = (String) mSillyFacesItem.get(index).get("value");
        } else if (parent == mBackgroundGrid) {
            value = (String) mBackgroundItem.get(index).get("value");
        } else {
            return;
        }

        // Tapping the selected effect will deselect it (clear effects).
        if (value.equals(mPreference.getValue())) {
            mPreference.setValue(mNoEffect);
        } else {
            mPreference.setValue(value);
        }
        reloadPreference();
        if (mListener != null) mListener.onSettingChanged();
    }

    @Override
    public void onClick(View v) {
        // Clear the effect.
        mPreference.setValue(mNoEffect);
        reloadPreference();
        if (mListener != null) mListener.onSettingChanged();
    }
}
