package jp.sourceforge.nicoro;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;

public class AccessHistoryActivity extends ListActivity {
    private static final int MSG_ID_THUMBINFO_FINISHED = 0;
    private static final int MSG_ID_THUMBINFO_OCCURRED_ERROR = 1;

    private AccessHistoryListAdapter mAdapter;
    private ProgressDialog mProgressDialogNowLoading;

    private boolean mWasDestroyed;

    private String mResStringInfoCountPlay;
    private String mResStringInfoCountComment;
    private String mResStringInfoCountMylist;
    private String mResStringUpload;
    private String mResStringAccess;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (mWasDestroyed) {
                return;
            }
            switch (msg.what) {
                case MSG_ID_THUMBINFO_FINISHED:
                    ThumbInfo thumbInfo = (ThumbInfo) msg.obj;
                    ListView listView = getListView();
                    int first = listView.getFirstVisiblePosition();
                    int last = listView.getLastVisiblePosition();
                    for (int i = first; i <= last; ++i) {
                        VideoLoader.ExternalInfoData data =
                            (VideoLoader.ExternalInfoData) mAdapter.getItem(i);
                        if (data.videoNumber.equals(thumbInfo.getVideoNumber())) {
                            // View更新
                            mAdapter.setListItem((ListItem) listView.getChildAt(
                                    i - first).getTag(), thumbInfo, data);
                            break;
                        }
                    }
                    break;
                case MSG_ID_THUMBINFO_OCCURRED_ERROR:
                    break;
                default:
                    assert false;
                    break;
            }
        }
    };

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

        mWasDestroyed = false;

        Resources res = getResources();
        mResStringInfoCountPlay = res.getString(R.string.info_count_play);
        mResStringInfoCountComment = res.getString(R.string.info_count_comment);
        mResStringInfoCountMylist = res.getString(R.string.info_count_mylist);
        mResStringUpload = res.getString(R.string.upload);
        mResStringAccess = res.getString(R.string.access);

        ListView listView = getListView();

        mAdapter = new AccessHistoryListAdapter();
        listView.setAdapter(mAdapter);
        final int colorBG = res.getColor(
                R.color.play_history_background);
        listView.setBackgroundColor(colorBG);
        listView.setCacheColorHint(colorBG);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                VideoLoader.ExternalInfoData data =
                    (VideoLoader.ExternalInfoData) mAdapter.getItem(position);
                if (data != null) {
                    // TODO 海外サイトどうする？
                    String url = "http://www.nicovideo.jp/watch/" + data.videoNumber;
                    Intent intent = new Intent(
                            Intent.ACTION_VIEW,
                            Uri.parse(url),
                            getApplicationContext(), NicoroWebBrowser.class);
                    intent.addCategory(Intent.CATEGORY_BROWSABLE);
                    startActivityIfNeeded(intent, 0);
                    finish();
                }
            }
        });

        new AsyncTask<Void, Void, ArrayList<VideoLoader.ExternalInfoData>>() {
            @Override
            protected ArrayList<VideoLoader.ExternalInfoData> doInBackground(Void... params) {
                ArrayList<VideoLoader.ExternalInfoData> cacheData =
                    VideoLoader.getCacheExternalInfoData();
                return cacheData;
            }

            @Override
            protected void onPostExecute(ArrayList<VideoLoader.ExternalInfoData> result) {
                if (mProgressDialogNowLoading != null) {
                    mProgressDialogNowLoading.dismiss();
                    mProgressDialogNowLoading = null;
                }
                mAdapter.setCacheData(result);
            }
        }.execute();

        mProgressDialogNowLoading = Util.createProgressDialogLoading(
                this, R.string.now_loading,
                new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        finish();
                    }
                });

        mProgressDialogNowLoading.show();
    }

    @Override
    protected void onDestroy() {
        mWasDestroyed = true;
        mAdapter.clearReserve();
        super.onDestroy();
    }

    private class AccessHistoryListAdapter extends BaseAdapter {
        private ThumbnailCacher mThumbnailCacher;
        private ThumbInfoCacher mThumbInfoCacher;
        private ArrayList<VideoLoader.ExternalInfoData> mCacheData;
        private HashSet<ThumbInfo> mThumbInfoReserve;

        private DateFormat mDateFormat = DateFormat.getDateTimeInstance(
                DateFormat.LONG, DateFormat.DEFAULT);

        public AccessHistoryListAdapter() {
            NicoroApplication app = NicoroApplication.getInstance(
                    AccessHistoryActivity.this);
            mThumbnailCacher = app.getThumbnailCacher();
            mThumbInfoCacher = app.getThumbInfoCacher();
            mCacheData = null;
        }

        @Override
        public int getCount() {
            if (mCacheData == null) {
                return 0;
            } else {
                return mCacheData.size();
            }
        }

        @Override
        public Object getItem(int position) {
            if (mCacheData == null) {
                return null;
            } else {
                return mCacheData.get(position);
            }
        }

        @Override
        public long getItemId(int position) {
            // TODO 自動生成されたメソッド・スタブ
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            assert mCacheData != null;
            View view;
            ListItem listItem;
            if (convertView == null) {
                LayoutInflater inflater = getLayoutInflater();
                view = inflater.inflate(R.layout.access_history, parent, false);
                listItem = new ListItem();
                view.setTag(listItem);
                listItem.time = (VariableLabelView) view.findViewById(R.id.time);
                listItem.timeAccess = (VariableLabelView) view.findViewById(R.id.time_access);
                listItem.title = (VariableLabelView) view.findViewById(R.id.title);
                listItem.view = (VariableLabelView) view.findViewById(R.id.view);
                listItem.comment = (VariableLabelView) view.findViewById(R.id.comment);
                listItem.mylist = (VariableLabelView) view.findViewById(R.id.mylist);
                listItem.length = (VariableLabelView) view.findViewById(R.id.length);
                listItem.thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
                listItem.loading = (VariableLabelView) view.findViewById(R.id.loading);
            } else {
                view = convertView;
                listItem = (ListItem) convertView.getTag();
            }

            String videoNumber = mCacheData.get(position).videoNumber;
            ThumbInfo thumbInfo = mThumbInfoCacher.getThumbInfo(videoNumber);
            if (thumbInfo == null) {
                clearListItem(listItem, mCacheData.get(position));
                mThumbInfoCacher.loadThumbInfo(videoNumber,
                        new CallbackMessage<ThumbInfo, String>(
                                mHandler,
                                MSG_ID_THUMBINFO_FINISHED,
                                MSG_ID_THUMBINFO_OCCURRED_ERROR));
            } else {
                setListItem(listItem, thumbInfo, mCacheData.get(position));
            }

            return view;
        }

        void setCacheData(ArrayList<VideoLoader.ExternalInfoData> cacheData) {
            mCacheData = cacheData;
            mThumbInfoReserve = new HashSet<ThumbInfo>(cacheData.size());
//            // 先行してチェック＆リクエスト
//            for (VideoLoader.ExternalInfoData data : cacheData) {
//                ThumbInfo thumbInfo = mThumbInfoCacher.getThumbInfo(
//                        data.videoNumber);
//                if (thumbInfo == null) {
//                    mThumbInfoCacher.loadThumbInfo(data.videoNumber, mHandler,
//                            MSG_ID_THUMBINFO_FINISHED,
//                            MSG_ID_THUMBINFO_OCCURRED_ERROR);
//                } else {
//                    mThumbInfoReserve.add(thumbInfo);
//                }
//            }

            getListView().invalidateViews();
        }

        void setListItem(ListItem listItem, ThumbInfo thumbInfo,
                VideoLoader.ExternalInfoData data) {
            mThumbInfoReserve.add(thumbInfo);

            Date time = thumbInfo.getFirstRetrieveAsDate();
            if (time != null) {
                listItem.time.getTextBuilderWithClear().append(mDateFormat.format(
                        time)).append(" ").append(mResStringUpload);
                listItem.time.notifyUpdateText();
            }
            listItem.time.setVisibility(View.VISIBLE);

            Date timePlay = new Date(data.lastPlayed);
            listItem.timeAccess.getTextBuilderWithClear().append(mDateFormat.format(
                    timePlay)).append(" ").append(mResStringAccess);
            listItem.timeAccess.notifyUpdateText();
            listItem.timeAccess.setVisibility(View.VISIBLE);

            listItem.title.setText(Util.convertHtmlSpecialCharacter(
                    thumbInfo.getTitle()));
            listItem.title.setVisibility(View.VISIBLE);

            listItem.view.getTextBuilderWithClear().append(mResStringInfoCountPlay
                    ).append(thumbInfo.getViewCounter());
            listItem.view.notifyUpdateText();
            listItem.view.setVisibility(View.VISIBLE);

            listItem.comment.getTextBuilderWithClear().append(mResStringInfoCountComment
                    ).append(thumbInfo.getCommentNum());
            listItem.comment.notifyUpdateText();
            listItem.comment.setVisibility(View.VISIBLE);

            listItem.mylist.getTextBuilderWithClear().append(mResStringInfoCountMylist
                    ).append(thumbInfo.getMylistCounter());
            listItem.mylist.notifyUpdateText();
            listItem.mylist.setVisibility(View.VISIBLE);

            listItem.length.setText(thumbInfo.getLength());
            listItem.length.setVisibility(View.VISIBLE);

            ViewGroup.LayoutParams params = listItem.thumbnail.getLayoutParams();
            String thumbnailUrl = thumbInfo.getThumbnailUrl();
            Bitmap bitmap = mThumbnailCacher.getThumbnail(thumbnailUrl);
            AsyncBitmapDrawable drawable;
            if (bitmap == null) {
                drawable = new AsyncBitmapDrawable(params.width, params.height);
                mThumbnailCacher.loadThumbnail(thumbnailUrl,
                        new CallbackMessage<Bitmap, Void>(
                                drawable.getHandler(), 0));
            } else {
                drawable = new AsyncBitmapDrawable(bitmap,
                        params.width, params.height);
            }
            listItem.thumbnail.setImageDrawable(drawable);
            listItem.thumbnail.setVisibility(View.VISIBLE);

            listItem.loading.setText("");
            listItem.loading.setVisibility(View.INVISIBLE);
        }

        void clearListItem(ListItem listItem,
                VideoLoader.ExternalInfoData data) {
//            listItem.time.setText("");
            listItem.time.setVisibility(View.INVISIBLE);
//            listItem.timeAccess.setText("");
            listItem.timeAccess.setVisibility(View.INVISIBLE);
//            listItem.title.setText("");
            listItem.title.setVisibility(View.INVISIBLE);
//            listItem.view.setText("");
            listItem.view.setVisibility(View.INVISIBLE);
//            listItem.comment.setText("");
            listItem.comment.setVisibility(View.INVISIBLE);
//            listItem.mylist.setText("");
            listItem.mylist.setVisibility(View.INVISIBLE);
//            listItem.length.setText("");
            listItem.length.setVisibility(View.INVISIBLE);
            listItem.thumbnail.setImageDrawable(null);
            listItem.thumbnail.setVisibility(View.INVISIBLE);

            listItem.loading.getTextBuilderWithClear().append(data.videoNumber
                    ).append(" loading...");
            listItem.loading.notifyUpdateText();
            listItem.loading.setVisibility(View.VISIBLE);
        }

        void clearReserve() {
            if (mThumbInfoReserve != null) {
                mThumbInfoReserve.clear();
            }
        }
    }

    private static class ListItem {
        public int position;

        public VariableLabelView time;
        public VariableLabelView timeAccess;
        public VariableLabelView title;
        public VariableLabelView view;
        public VariableLabelView comment;
        public VariableLabelView mylist;
        public VariableLabelView length;
        public ImageView thumbnail;

        public VariableLabelView loading;
    }
}
