package com.wasu.cs.widget.mediacontrol;

import android.annotation.SuppressLint;
import android.content.Context;
import android.media.MediaPlayer;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

import com.wasu.module.log.WLog;

import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
import java.util.Locale;

import cn.com.wasu.main.R;

/**
 * seek控制条
 */
@SuppressLint("NewApi") 
public class SeekbarController extends FrameLayout implements IMediaControllerChildView<MediaController>, OnSeekBarChangeListener {

	/**
	 * seekbar加减幅度默认30s
	 */
	private static int INCREMENT = 30000;
	private static float INCREMENT_DELTA = 1.0f;

	private MediaController mediaController;

	private TextView startPoint;
	private TextView totalDuration;
	private TextView currentDuration;
	private SeekBar seekbar;
	private ImageView seekIndicator;

	/**
	 * 允许seek的最大时间
	 */
	private int limitTime = Integer.MAX_VALUE;

	public int getLimitTime() {
		return limitTime;
	}

	public void setLimitTime(int limitTime) {
		this.limitTime = limitTime;
	}
	/**
	 * seekBar的宽度
	 * */
	private int mSeekBarWidth = -1;
	/**
	 * seekBar起点x坐标
	 */
	private float startX;

	/**
	 * 用户是否正在seek
	 */
	private boolean isSeeking;
	/**
	 * 播放器是否正在执行seek操作
	 */
	private boolean isPreformSeeking;

	/**
	 * 根据用户seek进度，更新seekbar和currentDuration
	 */
	private Runnable seekTask = new Runnable() {

		@Override
		public void run() {
            if (!mediaController.getPlayer().isInPlaybackState()) {
                return;
            }

			INCREMENT_DELTA = 1.0f;
			setSeekIndicatorVisible(false);
			mediaController.getPlayer().seekTo(seekbar.getProgress());
			isSeeking = false;
		}

	};
	
	public SeekbarController(Context context) {
		super(context);
		init(context);
	}

	public SeekbarController(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public SeekbarController(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context);
	}

	private void init(Context context) {
		setId(MediaController.generateID());

		LayoutInflater.from(context).inflate(R.layout.media_controller_seekbar, this);
		
		startPoint = (TextView) findViewById(R.id.start_point);
		startPoint.setText("00:00:00");
		totalDuration = (TextView) findViewById(R.id.total_duration);

		currentDuration = (TextView) findViewById(R.id.current_duration);

		seekbar = (SeekBar) findViewById(R.id.seekbar);
		
		seekIndicator = (ImageView) findViewById(R.id.seek_indicator);
		
		startX = seekbar.getLeft() + seekbar.getPaddingLeft();
		
		currentDuration.setTranslationX(startX);
	}
	
	private void setSeekIndicatorVisible(boolean isShow) {
		seekIndicator.setVisibility(isShow ? VISIBLE : INVISIBLE);
	}

	protected void resetSeekIndicatorToPause(){
		seekIndicator.setImageResource(R.drawable.media_controller_seekbar_pause_indicator);
	}

	@Override
	public boolean isAutoHide() {
		return true;
	}

	@Override
	public void onShow(final MediaController mediaController) {
		this.mediaController = mediaController;

		final int duration = mediaController.getPlayer().getDuration();
		final int currDuration = mediaController.getPlayer().getCurrentPosition();

		if (duration <= INCREMENT) {
			INCREMENT = duration / 10;
		} else {
			INCREMENT = 30000;
		}

		seekbar.setOnSeekBarChangeListener(this);
		
        currentDuration.setText(convertTimeMills2Str(currDuration));
        totalDuration.setText(convertTimeMills2Str(duration));

        seekbar.setMax(duration);
        seekbar.setKeyProgressIncrement(INCREMENT);
        seekbar.setProgress(currDuration);

		if (mSeekBarWidth < 0){
		seekbar.post(new Runnable() {
			@Override
			public void run() {
				mSeekBarWidth =seekbar.getMeasuredWidth();
				onProgressChanged(seekbar, currDuration, false);
			}
		});}else {
			onProgressChanged(seekbar, currDuration, false);
		}

        setSeekIndicatorVisible(!mediaController.getPlayer().isPlaying());
	}

	@Override
	public void onHide(MediaController mediaController) {
		seekbar.setOnSeekBarChangeListener(null);
	}

	@Override
	public boolean onShield(KeyEvent event) {
		boolean ret = false;
		if (event.getAction() == KeyEvent.ACTION_DOWN) {

			int progress = seekbar.getProgress();

			switch (event.getKeyCode()) {
			case KeyEvent.KEYCODE_DPAD_UP:
			case KeyEvent.KEYCODE_DPAD_DOWN:
			case KeyEvent.KEYCODE_VOLUME_UP:
			case KeyEvent.KEYCODE_VOLUME_DOWN:
			case KeyEvent.KEYCODE_VOLUME_MUTE:
			case KeyEvent.KEYCODE_MENU:
				// 2017/1/20 Add By Frewen.Wong 放SeekBar显示时候屏蔽其他按钮的功能
				//ret = true;
				//break;
			case KeyEvent.KEYCODE_DPAD_CENTER:
			case KeyEvent.KEYCODE_ENTER:
				ret = false;
				break;
			case KeyEvent.KEYCODE_BACK:
				break;
			case KeyEvent.KEYCODE_DPAD_LEFT:
				if (seekbar.getMax() < INCREMENT) {
					break;
				}
				
				seekIndicator.setImageResource(R.drawable.media_controller_seekbar_back_indicator);

				isSeeking = true;
				INCREMENT_DELTA *= 1.1f;
				setSeekIndicatorVisible(true);
				removeCallbacks(seekTask);

				progress -= INCREMENT * INCREMENT_DELTA;
				if (progress < 0) {
					progress = 0;
				}

				seekbar.setProgress(progress);
				currentDuration.setText(convertTimeMills2Str(progress));
				postDelayed(seekTask, 500);
				ret = true;
				break;
			case KeyEvent.KEYCODE_DPAD_RIGHT:
				if (seekbar.getMax() < INCREMENT) {
					break;
				}
				
				seekIndicator.setImageResource(R.drawable.media_controller_seekbar_forward_indicator);

				isSeeking = true;
				INCREMENT_DELTA *= 1.1f;
				setSeekIndicatorVisible(true);
				removeCallbacks(seekTask);

				progress += INCREMENT * INCREMENT_DELTA;

				if (progress > limitTime) {
					progress = limitTime;
				}

				if (progress > seekbar.getMax()) {
					progress = seekbar.getMax();
				}

				seekbar.setProgress(progress);
				currentDuration.setText(convertTimeMills2Str(progress));

				postDelayed(seekTask, 500);
				ret = true;
				break;
			default:
				ret = true;
				break;
			}

		}
		return ret;
	}

	@Override
	public void clear() {
		limitTime = Integer.MAX_VALUE;
		isSeeking = false;
		isPreformSeeking = false;

		removeCallbacks(seekTask);
	}

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
			float halfTextWidth = currentDuration.getMeasuredWidth() / 2.f;
			float seekbarWidth = mSeekBarWidth - seekbar.getPaddingLeft() - seekbar.getPaddingRight();

			float position = progress * 1.f / seekbar.getMax() * 1.f * seekbarWidth;
			position += startX;

			if (position <= halfTextWidth) {
				position = startX;
			} else if (position > halfTextWidth && position < mSeekBarWidth - halfTextWidth) {
				position = position - halfTextWidth;
			} else {
				position = startX + seekbarWidth;
			}

			currentDuration.setTranslationX(position);
	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {

	}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {

	}

	private String convertTimeMills2Str(int timeMs) {
		int totalSeconds = (int) (timeMs / 1000.f);
		int seconds = (int) (totalSeconds % 60.f);
		int minutes = (int) ((totalSeconds / 60.f) % 60.f);
		int hours = (int) (totalSeconds / 3600.f);
		StringBuilder sb = new StringBuilder();
		Formatter ft = new Formatter(sb, Locale.getDefault());
		String ret = "";
		sb.setLength(0);
		if (hours > 0) {
		    ret = ft.format("%d:%02d:%02d", hours, minutes, seconds).toString();
		    ft.close();
			return ret;
		} else {
		    ret = ft.format("%02d:%02d", minutes, seconds).toString();
		    ft.close();
			return ret;
		}
	}

	@Override
	public void onAdStatusChanged(int arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onCompletion(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onError(MediaPlayer arg0, int arg1, int arg2) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onInfo(MediaPlayer arg0, int arg1, int arg2) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onPause(MediaPlayer arg0) {
		seekIndicator.setImageResource(R.drawable.media_controller_seekbar_pause_indicator);
	}

	@Override
	public void onPrepareComplete(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onPreparing(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onProgress(int arg0, int arg1, int arg2) {
		if (isSeeking || isPreformSeeking || seekbar.getMax() == 100) {
			return;
		}

		int currDuration = mediaController.getPlayer().getCurrentPosition();
		seekbar.setProgress(currDuration);
		currentDuration.setText(convertTimeMills2Str(currDuration));
	}

	@Override
	public void onResume(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onSeekComplete(MediaPlayer arg0) {
		isPreformSeeking = false;
	}

	@Override
	public void onSeeking(MediaPlayer arg0) {
		isPreformSeeking = true;
	}

	@Override
	public void onStart(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStatusChanged(MediaPlayer arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStop(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onWasuError(int arg0, String arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onWasuPlayLimit(int arg0, String arg1) {
	}

	private List<IMediaControllerChildView<MediaController>> relativeViews = new ArrayList<IMediaControllerChildView<MediaController>>();
	
	@Override
	public void setRelativeViews(IMediaControllerChildView<MediaController>... views) {
		for (IMediaControllerChildView<MediaController> v : views) {
			if (!relativeViews.contains(v)) {
				relativeViews.add(v);
			}
		}
	}

	@Override
	public List<IMediaControllerChildView<MediaController>> getRelativeViews() {
		return relativeViews;
	}

}
