package jp.sourceforge.nicoro;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
//import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
//import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Spinner;

import jp.gr.java_conf.shiseissi.commonlib.DialogFragmentEx;
import jp.gr.java_conf.shiseissi.commonlib.ViewUtil;
import jp.sourceforge.nicoro.StaticRes.integer;

public class PlaylistDialogFragment extends DialogFragmentEx
implements ViewTreeObserver.OnGlobalLayoutListener {
    private Context mContext;

    private VariableLabelView mViewTitle;
    private ListView mListView;
    private Spinner mSpinnerSort;

    Playlist mPlaylist;

    LayoutInflater mLayoutInflater;

    int mResPlaylistTextColor;
    int mResPlaylistTextColorDeleted;
    int mResPlaylistTextColorCurrent;

    int mCurrentTrack;

    public static PlaylistDialogFragment createInstance() {
        PlaylistDialogFragment fragment = new PlaylistDialogFragment();
        return fragment;
    }

    public PlaylistDialogFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Activity activity = getActivity();

        mContext = activity.getApplicationContext();

        if (activity instanceof Interface) {
            Playlist pl = ((Interface) activity).getPlaylist();
            if (pl != null) {
                mPlaylist = new Playlist(pl);
            }
        }

        if (mPlaylist == null) {
            Util.showErrorToast(mContext, R.string.errormessage_unknown);
            // エラー終了
            dismissSafely();
        } else {
            mCurrentTrack = mPlaylist.getCurrentTrack();
        }

        setStyle(DialogFragment.STYLE_NO_TITLE, R.style.Theme_Dialog_Playlist);
        setCancelable(true);

        Resources res = getResources();
        mResPlaylistTextColor = res.getColor(R.color.playlist_text_color);
        mResPlaylistTextColorDeleted = res.getColor(R.color.playlist_text_color_deleted);
        mResPlaylistTextColorCurrent = res.getColor(R.color.playlist_text_color_current);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mLayoutInflater = inflater;

        View view = inflater.inflate(R.layout.playlist_dialog, container, false);
        mViewTitle = ViewUtil.findViewById(view, R.id.title);

        mSpinnerSort = ViewUtil.findViewById(view, R.id.spinner_sort);

        mListView = ViewUtil.findViewById(view, android.R.id.list);

        View viewClose = ViewUtil.findViewById(view, android.R.id.closeButton);
        viewClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismissSafely();
            }
        });

        Button buttonShuffle = ViewUtil.findViewById(view, R.id.button_shuffle);

        if (mPlaylist != null) {
            mViewTitle.setText(mPlaylist.getName());

            Activity activity = getActivity();
            ArrayAdapter<?> sortAdapter = ArrayAdapter.createFromResource(activity,
                    R.array.mylist_sort_playlist, R.layout.mylist_spinner_item);
            sortAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            mSpinnerSort.setAdapter(sortAdapter);
            // listener設定前に初期アイテム選択
            mSpinnerSort.setSelection(mPlaylist.getSortOrder());
            mSpinnerSort.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    // XXX ランダム選択後、Spinnerで同じアイテムを再選択してもソートが起きない（onItemSelectedが呼ばれない）
                    Activity a = getActivity();
                    if (a instanceof Interface) {
                        ((Interface) a).onPlaylistSortItemClick(
                                PlaylistDialogFragment.this, position);
                    }
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                }
            });

            buttonShuffle.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Activity a = getActivity();
                    if (a instanceof Interface) {
                        ((Interface) a).onPlaylistShuffleItemClick(
                                PlaylistDialogFragment.this);
                    }
                    // ランダム時はダミー選択
                    mSpinnerSort.setSelection(integer.mylist_sort_dummy);
                }
            });

            PlaylistAdapter adapter = new PlaylistAdapter();
            mListView.setAdapter(adapter);
            mListView.setSelectionFromTop(mCurrentTrack,
                    mListView.getVerticalFadingEdgeLength());
            mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Activity a = getActivity();
                    if (a instanceof Interface) {
                        ((Interface) a).onPlaylistItemClick(
                                PlaylistDialogFragment.this, position);
                        dismissSafely();
                    }
                }
            });
        }

        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        getView().getViewTreeObserver().addOnGlobalLayoutListener(this);
        updateDialogLayout();
    }

    @Override
    public void onDestroyView() {
        getView().getViewTreeObserver().removeGlobalOnLayoutListener(this);

        super.onDestroyView();
    }

    @Override
    public void onGlobalLayout() {
        updateDialogLayout();
    }

    private void updateDialogLayout() {
        Window window = getDialog().getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();

        DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
        int dialogWidth = dm.widthPixels * 5 / 6;
        if (lp.width != dialogWidth) {
            lp.width = dialogWidth;
            window.setAttributes(lp);
        }
    }

    public void setCurrentTrack(int current) {
        int lastTrack = mCurrentTrack;
        mCurrentTrack = current;

        ListView listView = mListView;
        if (listView != null && listView.getAdapter() != null) {
            int first = listView.getFirstVisiblePosition();
            int last = listView.getLastVisiblePosition();
            if (current >= first && current <= last) {
                View view = listView.getChildAt(current - first);
                if (view != null) {
                    ListItem listItem = (ListItem) view.getTag();
                    listItem.track.setTextColor(mResPlaylistTextColorCurrent);
                    listItem.title.setTextColor(mResPlaylistTextColorCurrent);
                    listItem.time.setTextColor(mResPlaylistTextColorCurrent);
                }
            }

            if (lastTrack >= first && lastTrack <= last) {
                View view = listView.getChildAt(lastTrack - first);
                if (view != null) {
                    ListItem listItem = (ListItem) view.getTag();
                    // XXX 事前にcurrent trackだったのでdeletedではないはず
                    listItem.track.setTextColor(mResPlaylistTextColor);
                    listItem.title.setTextColor(mResPlaylistTextColor);
                    listItem.time.setTextColor(mResPlaylistTextColor);
                }
            }
        }
    }

    public void notifyPlaylistChanged() {
        Activity activity = getActivity();
        if (activity instanceof Interface) {
            Playlist pl = ((Interface) activity).getPlaylist();
            if (pl != null) {
                mPlaylist = new Playlist(pl);
                mCurrentTrack = mPlaylist.getCurrentTrack();
                AdapterView.OnItemSelectedListener listener =
                    mSpinnerSort.getOnItemSelectedListener();
                mSpinnerSort.setOnItemSelectedListener(null);
                mSpinnerSort.setSelection(mPlaylist.getSortOrder());
                mSpinnerSort.setOnItemSelectedListener(listener);
                PlaylistAdapter adapter = (PlaylistAdapter) mListView.getAdapter();
                adapter.notifyDataSetChanged();
                mListView.setSelectionFromTop(mCurrentTrack,
                        mListView.getVerticalFadingEdgeLength());
            }
        }
    }

    private class PlaylistAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return mPlaylist.getItemsSize();
        }

        @Override
        public Object getItem(int position) {
            return mPlaylist.getItem(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view;
            ListItem listItem;
            if (convertView == null) {
                view = mLayoutInflater.inflate(R.layout.playlist_item, parent, false);
                listItem = new ListItem();
                view.setTag(listItem);
                listItem.track = ViewUtil.findViewById(view, R.id.track);
                listItem.title = ViewUtil.findViewById(view, R.id.title);
                listItem.time = ViewUtil.findViewById(view, R.id.time);
            } else {
                view = convertView;
                listItem = (ListItem) view.getTag();
            }

            listItem.track.getTextBuilderWithClear().append(position + 1);
            listItem.track.notifyUpdateText();

            Playlist.Item item = mPlaylist.getItem(position);
            if (item == null) {
                // fail safe
                listItem.title.setText("");
                listItem.time.setText("");

                listItem.track.setTextColor(mResPlaylistTextColor);
                listItem.title.setTextColor(mResPlaylistTextColor);
                listItem.time.setTextColor(mResPlaylistTextColor);
            } else {
                listItem.title.getTextBuilderWithClear().append(
                        Util.convertHtmlEscapedCharacter(item.title));
                listItem.title.notifyUpdateText();

                Util.appendPlayTime(listItem.time.getTextBuilderWithClear(),
                        item.lengthSeconds / 60, item.lengthSeconds % 60);
                listItem.time.notifyUpdateText();

                if (item.isDeleted()) {
                    listItem.track.setTextColor(mResPlaylistTextColorDeleted);
                    listItem.title.setTextColor(mResPlaylistTextColorDeleted);
                    listItem.time.setTextColor(mResPlaylistTextColorDeleted);
                } else if (position == mCurrentTrack) {
                    listItem.track.setTextColor(mResPlaylistTextColorCurrent);
                    listItem.title.setTextColor(mResPlaylistTextColorCurrent);
                    listItem.time.setTextColor(mResPlaylistTextColorCurrent);
                } else {
                    listItem.track.setTextColor(mResPlaylistTextColor);
                    listItem.title.setTextColor(mResPlaylistTextColor);
                    listItem.time.setTextColor(mResPlaylistTextColor);
                }
            }

            return view;
        }
    }

    private static class ListItem {
        VariableLabelView track;
        VariableLabelView title;
        VariableLabelView time;
    }

    public interface Interface {
        void onPlaylistItemClick(PlaylistDialogFragment fragment, int position);
        void onPlaylistSortItemClick(PlaylistDialogFragment fragment, int position);
        void onPlaylistShuffleItemClick(PlaylistDialogFragment fragment);
        Playlist getPlaylist();
    }
}
