package jp.sourceforge.nicoro;

import android.app.Activity;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.ToggleButton;

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

import static jp.sourceforge.nicoro.Log.LOG_TAG;

public class PlayerControllerViews {
    private static final boolean DEBUG_LOGD = Release.IS_DEBUG & true;

    /** nullの可能性あり */
    private ImageButton mButtonPause;
    /** nullの可能性あり */
    private ImageButton mButtonFromBegin;
    private ToggleButton mButtonCommentOnOff;
    private ImageButton mButtonMore;
    private ImageButton mButtonHide;
    /** nullの可能性あり */
    private SeekBar mSeekBar;
    /** nullの可能性あり */
    private TextView mContributorForbidSeek;
    /** nullの可能性あり */
    private EditText mCommentMail;
    /** nullの可能性あり */
    private EditText mCommentBody;
    /** nullの可能性あり */
    private Button mButtonSendComment;
    /** nullの可能性あり */
    private ImageButton mButtonSpeak;
    private ViewGroup mPlayerController;

    SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener;
    OnSendCommentClickListener mOnSendCommentClickListener;
    boolean mIsTrackingSeekBar = false;
    View.OnClickListener mOnSpeakClickListener;

    OnCommentControllerClickListener mOnCommentControllerClickListener;

    public void initializeView(Activity activity) {
        View root = activity.getWindow().getDecorView();
        initializeView(root);
    }

    public void initializeView(View root) {
        mButtonPause = ViewUtil.findViewById(root, R.id.button_pause);
        mButtonFromBegin = ViewUtil.findViewById(root, R.id.button_from_begin);
        mButtonCommentOnOff = ViewUtil.findViewById(root, R.id.button_comment_onoff);
        mButtonMore = ViewUtil.findViewById(root, R.id.button_more);
        mButtonHide = ViewUtil.findViewById(root, R.id.button_hide);
        mSeekBar = ViewUtil.findViewById(root, R.id.seek_bar);
        mContributorForbidSeek = ViewUtil.findViewById(root, R.id.contributor_forbid_seek);
        mCommentMail = ViewUtil.findViewById(root, R.id.comment_mail);
        mCommentBody = ViewUtil.findViewById(root, R.id.comment_body);
        mButtonSendComment = ViewUtil.findViewById(root, R.id.button_send_comment);
        mButtonSpeak = ViewUtil.findViewById(root, R.id.button_speak);
        mPlayerController = ViewUtil.findViewById(root, R.id.player_controller);

        if (mCommentMail != null) {
            mCommentMail.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mOnCommentControllerClickListener != null) {
                        mOnCommentControllerClickListener.onClick();
                    }
                }
            });
            mCommentMail.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    if (hasFocus) {
                        if (mOnCommentControllerClickListener != null) {
                            mOnCommentControllerClickListener.onClick();
                        }
                    }
                }
            });
        }
        if (mCommentBody != null) {
            mCommentBody.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mOnCommentControllerClickListener != null) {
                        mOnCommentControllerClickListener.onClick();
                    }
                }
            });
            mCommentBody.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    if (hasFocus) {
                        if (mOnCommentControllerClickListener != null) {
                            mOnCommentControllerClickListener.onClick();
                        }
                    }
                }
            });

            TextWatcher commentWatcher = new TextWatcher() {
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                }
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }
                @Override
                public void afterTextChanged(Editable s) {
                    updateButtonSendComment();
                }
            };
            mCommentBody.addTextChangedListener(commentWatcher);
            updateButtonSendComment();
        }

        if (mSeekBar != null) {
            mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress,
                        boolean fromUser) {
                    assert seekBar == mSeekBar;
                    if (mOnSeekBarChangeListener != null) {
                        mOnSeekBarChangeListener.onProgressChanged(seekBar, progress,
                                fromUser);
                    }
                }
                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {
                    mIsTrackingSeekBar = true;
                    assert seekBar == mSeekBar;
                    if (mOnSeekBarChangeListener != null) {
                        mOnSeekBarChangeListener.onStartTrackingTouch(seekBar);
                    }
                }
                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {
                    mIsTrackingSeekBar = false;
                    assert seekBar == mSeekBar;
                    if (mOnSeekBarChangeListener != null) {
                        mOnSeekBarChangeListener.onStopTrackingTouch(seekBar);
                    }
                }
            });
        }

        if (mButtonSendComment != null) {
            mButtonSendComment.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    assert mCommentMail != null;
                    assert mCommentBody != null;
                    String mail = mCommentMail.getText().toString();
                    // mailは同じスタイルで連続送信できるよう初期化しない
                    String body = mCommentBody.getText().toString();
                    mCommentBody.setText("");
                    if (mOnSendCommentClickListener != null) {
                        mOnSendCommentClickListener.onClick(mail, body);
                    }
                }
            });
        }

        if (mButtonSpeak != null) {
            mButtonSpeak.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mOnCommentControllerClickListener != null) {
                        mOnCommentControllerClickListener.onClick();
                    }

                    if (mOnSpeakClickListener != null) {
                        mOnSpeakClickListener.onClick(v);
                    }
                }
            });
        }
    }

    public void setButtonPauseOnClickListener(View.OnClickListener listener) {
        if (mButtonPause == null) {
            return;
        }
        mButtonPause.setOnClickListener(listener);
    }
    public void setButtonFromBeginOnClickListener(View.OnClickListener listener) {
        if (mButtonFromBegin == null) {
            return;
        }
        mButtonFromBegin.setOnClickListener(listener);
    }
    public void setButtonCommentOnOffOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener listener) {
        mButtonCommentOnOff.setOnCheckedChangeListener(listener);
    }

    public void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener listener) {
        mOnSeekBarChangeListener = listener;
    }

    public void setOnSendCommentClickListener(OnSendCommentClickListener listener) {
        mOnSendCommentClickListener = listener;
    }

    public void setOnSpeakClickListener(View.OnClickListener listener) {
        mOnSpeakClickListener = listener;
    }

    public void setOnCommentControllerClickListener(OnCommentControllerClickListener listener) {
        mOnCommentControllerClickListener = listener;
    }

    public void setButtonMoreOnClickListener(View.OnClickListener listener) {
        if (mButtonMore == null) {
            return;
        }
        mButtonMore.setOnClickListener(listener);
    }

    public void setButtonHideOnClickListener(View.OnClickListener listener) {
        if (mButtonHide == null) {
            return;
        }
        mButtonHide.setOnClickListener(listener);
    }

    public void copyLayoutParamsFrom(ViewGroup src) {
    }

    public void setButtonPauseImage(boolean isPausePlay) {
        if (mButtonPause == null) {
            return;
        }
        int icon;
        // 一時停止中は再生ボタン、再生中は一時停止ボタンを表示
        if (isPausePlay) {
            icon = android.R.drawable.ic_media_play;
        } else {
            icon = android.R.drawable.ic_media_pause;
        }
        mButtonPause.setImageResource(icon);
    }

    public void setEnabledSeekController(boolean enabled) {
        if (enabled && mContributorForbidSeek != null
                && mContributorForbidSeek.getVisibility() == View.VISIBLE) {
            if (DEBUG_LOGD) {
                Log.d(LOG_TAG, "Contributor forbid seek is visible, ignore enable seek controller");
            }
            return;
        }
        if (mSeekBar != null) {
            mSeekBar.setEnabled(enabled);
        }
        if (mButtonFromBegin != null) {
            mButtonFromBegin.setEnabled(enabled);
        }
    }

    public ViewGroup getControllerView() {
        return mPlayerController;
    }

    /**
     * SeekBarの最大値を設定
     * @param second 最大値（秒）
     */
    public void setSeekBarMax(int second) {
        if (mSeekBar == null) {
            return;
        }
        mSeekBar.setMax(second);
    }

    /**
     * SeekBarのcurrent progressを設定
     * @param second （秒）
     */
    public void setSeekBarProgress(int second) {
        if (mSeekBar == null) {
            return;
        }
        mSeekBar.setProgress(second);
    }

    /**
     * SeekBarのsecondary progressを分数で設定
     * @param num 分子
     * @param den 分母
     */
    public void setSeekBarSecondaryProgress(long num, int den) {
        if (mSeekBar == null) {
            return;
        }
        mSeekBar.setSecondaryProgress(
                (int) ((long) mSeekBar.getMax() * num / den));
    }

    /**
     * SeekBarのsecondary progressを現在の最大値に設定
     */
    public void setSeekBarSecondaryMax() {
        if (mSeekBar == null) {
            return;
        }
        mSeekBar.setSecondaryProgress(mSeekBar.getMax());
    }

    public boolean canUpdateSeekBarProgress() {
        if (mSeekBar == null) {
            return false;
        }
        return !mIsTrackingSeekBar && mSeekBar.isEnabled();
    }

    public void setCheckedButtonCommentOnOff(boolean checked) {
        mButtonCommentOnOff.setChecked(checked);
    }

    public void setContributorForbidSeekVisibility(boolean visible) {
        if (mContributorForbidSeek == null) {
            return;
        }
        mContributorForbidSeek.setVisibility(
                visible ? View.VISIBLE : View.GONE);
    }

    public void enableComment() {
        if (mCommentMail != null) {
            mCommentMail.setEnabled(true);
        }
        if (mCommentBody != null) {
            mCommentBody.setEnabled(true);
            mCommentBody.setHint(null);
        }
        if (mButtonSpeak != null) {
            mButtonSpeak.setEnabled(true);
        }
    }

    public void disableComment(String disableMessage) {
        if (mCommentMail != null) {
            mCommentMail.setEnabled(false);
        }
        if (mCommentBody != null) {
            mCommentBody.setEnabled(false);
            mCommentBody.setText("");
            mCommentBody.setHint(disableMessage);
        }
        if (mButtonSpeak != null) {
            mButtonSpeak.setEnabled(false);
        }
    }

    void updateButtonSendComment() {
        if (mButtonSendComment == null) {
            return;
        }

        boolean hasText = false;
        if (mCommentBody != null) {
            if (!TextUtils.isEmpty(mCommentBody.getText())) {
                hasText = true;
            }
        }
        mButtonSendComment.setEnabled(hasText);
    }

    public void setSpeakVisibility(boolean visible) {
        if (mButtonSpeak == null) {
            return;
        }
        mButtonSpeak.setVisibility(
                visible ? View.VISIBLE : View.GONE);
    }

    public void addCommentBody(String text) {
        if (mCommentBody == null) {
            return;
        }
        mCommentBody.getText().append(text);
    }

    public interface OnSendCommentClickListener {
        public void onClick(String mail, String body);
    }
    public interface OnCommentControllerClickListener {
        public void onClick();
    }
}
