package jp.sourceforge.nicoro;

import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.UnderlineSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

import jp.gr.java_conf.shiseissi.commonlib.DialogFragmentEx;
import jp.gr.java_conf.shiseissi.commonlib.ViewUtil;

public class PlayerInfoDialogFragment extends DialogFragmentEx {
    public interface PlayDataAppender {
        StringBuilder appendMovieType(StringBuilder builder);
        StringBuilder appendVideoResolution(StringBuilder builder);
        StringBuilder appendPlayerInfo(StringBuilder builder);
    }

    public interface TimeAppender {
        StringBuilder appendCurrentPlayTime(StringBuilder builder);
        StringBuilder appendTotalPlayTime(StringBuilder builder);
        boolean hasTotalPlayTime();
    }

    private static final String KEY_IS_LIVE = "is_live";
    private static final String KEY_TITLE = "title";
    private static final String KEY_DESCRIPTION = "description";
    private static final String KEY_FIRST_RETRIEVE = "first_retrieve";
    private static final String KEY_THUMBNAIL_URL = "thumbnail_url";
    private static final String KEY_COUNT_PLAY = "count_play";
    private static final String KEY_COUNT_COMMENT = "comment";
    private static final String KEY_COUNT_MYLIST = "mylist";
    private static final String KEY_PLAY_DATA = "play_data";
    private static final String KEY_TAG_LIST = "tag_list";
    private static final String KEY_SHEET = "sheet";
    private static final String KEY_IS_DIALOG = "is_dialog";

    private Resources mResources;

    private boolean mIsLive = false;
    private boolean mIsDialog = true;
    private String mTitle = null;
    private String mDescription = null;
    private String mFirstRetrieve = null;
    private String mThumbnailUrl = null;
    private int mCountPlay = -1;
    private int mCountComment = -1;
    private int mCountMylist = -1;
    private String mPlayData = null;
    private String[] mTagList = null;
    private String mSheet = null;

    private ThumbnailCacher mThumbnailCacher;

    private VariableLabelView mViewTitle;
    private TextView mViewDescription;
    private VariableLabelView mViewFirstRetrieve;
    private VariableLabelView mViewPlayData;
    private TextView mViewTagList;
    private ImageView mViewThumbnail;
    private VariableLabelView mViewCountPlay;
    private VariableLabelView mViewCountComment;
    private VariableLabelView mViewCountMylist;

    public static PlayerInfoDialogFragment createInstanceForVideoDialog() {
        PlayerInfoDialogFragment fragment = new PlayerInfoDialogFragment();
        Bundle args = new Bundle(2);
        args.putBoolean(KEY_IS_DIALOG, true);
        args.putBoolean(KEY_IS_LIVE, false);
        fragment.setArguments(args);
        return fragment;
    }

    public static PlayerInfoDialogFragment createInstanceForLiveDialog() {
        PlayerInfoDialogFragment fragment = new PlayerInfoDialogFragment();
        Bundle args = new Bundle(2);
        args.putBoolean(KEY_IS_DIALOG, true);
        args.putBoolean(KEY_IS_LIVE, true);
        fragment.setArguments(args);
        return fragment;
    }

    public static PlayerInfoDialogFragment createInstanceForVideoLayout() {
        PlayerInfoDialogFragment fragment = new PlayerInfoDialogFragment();
        Bundle args = new Bundle(2);
        args.putBoolean(KEY_IS_DIALOG, false);
        args.putBoolean(KEY_IS_LIVE, false);
        fragment.setArguments(args);
        return fragment;
    }

    public static PlayerInfoDialogFragment createInstanceForLiveLayout() {
        PlayerInfoDialogFragment fragment = new PlayerInfoDialogFragment();
        Bundle args = new Bundle(2);
        args.putBoolean(KEY_IS_DIALOG, false);
        args.putBoolean(KEY_IS_LIVE, true);
        fragment.setArguments(args);
        return fragment;
    }

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

        // 上書き
        mResources = getResources();

        Bundle args = getArguments();
        if (args != null) {
            mIsLive = args.getBoolean(KEY_IS_LIVE, false);
            mIsDialog = args.getBoolean(KEY_IS_DIALOG, true);
        }

        if (savedInstanceState != null) {
            if (mTitle == null) {
                mTitle = savedInstanceState.getString(KEY_TITLE);
            }
            if (mDescription == null) {
                mDescription = savedInstanceState.getString(KEY_DESCRIPTION);
            }
            if (mFirstRetrieve == null) {
                mFirstRetrieve = savedInstanceState.getString(KEY_FIRST_RETRIEVE);
            }
            if (mThumbnailUrl == null) {
                mThumbnailUrl = savedInstanceState.getString(KEY_THUMBNAIL_URL);
            }
            if (mCountPlay < 0) {
                mCountPlay = savedInstanceState.getInt(KEY_COUNT_PLAY);
            }
            if (mCountComment < 0) {
                mCountComment = savedInstanceState.getInt(KEY_COUNT_COMMENT);
            }
            if (mCountMylist < 0) {
                mCountMylist = savedInstanceState.getInt(KEY_COUNT_MYLIST);
            }
            if (mPlayData == null) {
                mPlayData = savedInstanceState.getString(KEY_PLAY_DATA);
            }
            if (mTagList == null) {
                mTagList = savedInstanceState.getStringArray(KEY_TAG_LIST);
            }
            if (mSheet == null) {
                mSheet = savedInstanceState.getString(KEY_SHEET);
            }
        }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(
                R.layout.player_info_window, container, false);
        mViewTitle = ViewUtil.findViewById(view, R.id.title);
        setTitleInner(mTitle);
        mViewDescription = ViewUtil.findViewById(view,
                R.id.description);
        setDescriptionInner(mDescription);
        mViewFirstRetrieve = ViewUtil.findViewById(view,
                R.id.first_retrieve);
        setFirstRetrieveInner(mFirstRetrieve);

        mViewPlayData = ViewUtil.findViewById(view, R.id.play_data);
        setPlayDataInner(mPlayData);

        mViewTagList = ViewUtil.findViewById(view, R.id.tag_list);
        setTagListInner(mTagList);

        mViewThumbnail = ViewUtil.findViewById(view,
                R.id.thumbnail);
        setThumbnailUrlInner(mThumbnailUrl);

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

            view.setBackgroundColor(getResources().getColor(
                    R.color.player_info_view_background));
        }

        mViewCountPlay = ViewUtil.findViewById(view,
                R.id.count_play);
        setCountPlayInner(mCountPlay);
        mViewCountComment = ViewUtil.findViewById(view,
                R.id.count_comment);
        setCountCommentInner(mCountComment);
        mViewCountMylist = ViewUtil.findViewById(view,
                R.id.count_mylist);
        if (mIsLive) {
            setSheetInner(mSheet);
        } else {
            setCountMylistInner(mCountMylist);
        }

        return view;
    }

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

        if (mIsDialog) {
            getDialog().getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putString(KEY_TITLE, mTitle);
        outState.putString(KEY_DESCRIPTION, mDescription);
        outState.putString(KEY_FIRST_RETRIEVE, mFirstRetrieve);
        outState.putString(KEY_THUMBNAIL_URL, mThumbnailUrl);
        outState.putInt(KEY_COUNT_PLAY, mCountPlay);
        outState.putInt(KEY_COUNT_COMMENT, mCountComment);
        outState.putInt(KEY_COUNT_MYLIST, mCountMylist);
        outState.putString(KEY_PLAY_DATA, mPlayData);
        outState.putStringArray(KEY_TAG_LIST, mTagList);
        outState.putString(KEY_SHEET, mSheet);
    }

    public static void setPlayData(PlayDataAppender appender,
            StringBuilder builderInfoPlayData, Resources res) {
        builderInfoPlayData.append(res.getString(R.string.info_play_data_pre));
        appender.appendMovieType(builderInfoPlayData);
        builderInfoPlayData.append(' ');
        appender.appendVideoResolution(builderInfoPlayData).append(' ');
        appender.appendPlayerInfo(builderInfoPlayData);
    }

    public void setTitle(String text) {
        mTitle = text;
        if (mViewTitle != null) {
            setTitleInner(text);
        }
    }
    private void setTitleInner(String text) {
        mViewTitle.setText(text);
    }

    public void setDescription(String text) {
        mDescription = text;
        if (mViewDescription != null) {
            setDescriptionInner(text);
        }
    }
    private void setDescriptionInner(String text) {
        if (text == null) {
            mViewDescription.setText("");
        } else {
            mViewDescription.setText(Html.fromHtml(text));
        }
    }

    public void setFirstRetrieve(String text) {
        mFirstRetrieve = text;
        if (mViewFirstRetrieve != null) {
            setFirstRetrieveInner(text);
        }
    }
    private void setFirstRetrieveInner(String text) {
        if (text == null) {
            mViewFirstRetrieve.setVisibility(View.GONE);
        } else {
            mViewFirstRetrieve.setVisibility(View.VISIBLE);
            mViewFirstRetrieve.setText(text);
        }
    }

    public void setPlayData(String text) {
        mPlayData = text;
        if (mViewPlayData != null) {
            setPlayDataInner(text);
        }
    }
    private void setPlayDataInner(String text) {
        mViewPlayData.setText(text);
    }

    public void setTagList(List<String> list) {
        mTagList = list.toArray(new String[list.size()]);
        if (mViewTagList != null) {
            setTagListInner(mTagList);
        }
    }
    private void setTagListInner(String[] list) {
        if (list == null) {
            mViewTagList.setText("");
        } else {
            Resources res = mResources;
            SpannableStringBuilder builder = new SpannableStringBuilder(res.getString(R.string.tag))
                .append(":  ");
            for (String tag : mTagList) {
                int start = builder.length();
                builder.append(tag);
                UnderlineSpan span = new UnderlineSpan();
                builder.setSpan(span, start, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                builder.append("  ");
            }
            mViewTagList.setText(builder);
        }
    }

    public void setThumbnailUrl(String url) {
        mThumbnailUrl = url;
        if (mViewThumbnail != null) {
            setThumbnailUrlInner(url);
        }
    }
    private void setThumbnailUrlInner(String url) {
        ViewGroup.LayoutParams paramsThumbnail = mViewThumbnail.getLayoutParams();
        if (url == null) {
            ViewGroup.LayoutParams params = mViewThumbnail.getLayoutParams();
            params.width = 0;
            mViewThumbnail.setMinimumWidth(0);
            mViewThumbnail.setMaxWidth(0);
        } else {
            mThumbnailCacher = NicoroApplication.getInstance(getActivity()
                    ).getThumbnailCacher();
            AsyncBitmapDrawable drawable;
            Bitmap bitmap = mThumbnailCacher.getThumbnail(url);
            if (bitmap == null) {
                drawable = new AsyncBitmapDrawable(
                        paramsThumbnail.width, paramsThumbnail.height, true);
                mThumbnailCacher.loadThumbnail(url,
                        new CallbackMessage<Bitmap, Void>(
                                drawable.getHandler(), 0));
            } else {
                drawable = new AsyncBitmapDrawable(bitmap,
                        paramsThumbnail.width, paramsThumbnail.height, true);
            }
            mViewThumbnail.setImageDrawable(drawable);
        }
    }

    public void setCountPlay(int value) {
        mCountPlay = value;
        if (mViewCountPlay != null) {
            setCountPlayInner(value);
        }
    }
    private void setCountPlayInner(int value) {
        Resources res = mResources;
        if (mIsLive) {
            mViewCountPlay.getTextBuilderWithClear()
                .append(res.getString(R.string.info_live_count_watch))
                .append(value);
            mViewCountPlay.notifyUpdateText();
        } else {
            mViewCountPlay.getTextBuilderWithClear()
                .append(res.getString(R.string.info_count_play))
                .append(value);
            mViewCountPlay.notifyUpdateText();
        }
    }

    public void setCountComment(int value) {
        mCountComment = value;
        if (mViewCountComment != null) {
            setCountCommentInner(value);
        }
    }
    private void setCountCommentInner(int value) {
        Resources res = mResources;
        if (mIsLive) {
            mViewCountComment.getTextBuilderWithClear()
                .append(res.getString(R.string.info_live_count_comment))
                .append(value);
            mViewCountComment.notifyUpdateText();
        } else {
            mViewCountComment.getTextBuilderWithClear()
                .append(res.getString(R.string.info_count_comment))
                .append(value);
            mViewCountComment.notifyUpdateText();
        }
    }

    public void setCountMylist(int value) {
        mCountMylist = value;
        if (mViewCountMylist != null) {
            setCountMylistInner(value);
        }
    }
    private void setCountMylistInner(int value) {
        Resources res = mResources;
        mViewCountMylist.getTextBuilderWithClear()
            .append(res.getString(R.string.info_count_mylist))
            .append(value);
        mViewCountMylist.notifyUpdateText();
    }

    public void setSheet(String text) {
        mSheet = text;
        if (mViewCountMylist != null) {
            setSheetInner(text);
        }
    }
    private void setSheetInner(String text) {
        // マイリストのViewでsheetを表示
        mViewCountMylist.getTextBuilderWithClear()
            .append(text);
        mViewCountMylist.notifyUpdateText();
    }
}
