package com.gh.download;

import android.content.Context;
import android.os.Handler;
import android.os.Message;

import com.gh.common.constant.Constants;
import com.gh.common.util.FileUtils;
import com.gh.common.util.Utils;

import java.text.DecimalFormat;
import java.util.Iterator;
import java.util.Map;

public class DownloadTask implements DownloadListener {

	private DownloadEntity entry;
	private Handler handler;
	private Context context;
	private DownloadThread downloadThread;

	private double currPercent;
	private long totalSize;
	private long currSize;

	// 计算下载速度
	private long lastTime;
	private long intervalDownloadedSize;

	public DownloadTask(Handler handler, final DownloadEntity entry,
			Context context) {

		this.entry = entry;
		this.handler = handler;

		this.context = context;
		DownloadEntity historyEntry = DownloadDao.getInstance(context).get(
				entry.getUrl());
		if (historyEntry != null && historyEntry.getSize() != 0) {
			// 历史下载任务，初始化数据
			this.totalSize = entry.getSize();
			this.currPercent = (int) (entry.getProgress() * 100L / totalSize);
			Utils.log(DownloadTask.class.getSimpleName(),
					"DownloadTask==>" + "历史下载任务，初始化数据");
		} else {
			// 第一次下载
			this.currSize = 0;
			this.currPercent = 0;
		}

	}

	public void start() {
		// 从下载历史里获取过去下载的进度信息
		DownloadEntity downloadEntity = DownloadDao.getInstance(context).get(entry.getUrl());

		if (downloadEntity != null) {
			entry = downloadEntity;
			entry.setStatus(DownloadStatus.downloading);
			Utils.log(DownloadTask.class.getSimpleName(),
					"start==>" + "load from history:" + entry.getUrl()
							+ "--" + entry.getProgress() + "," + entry.getSize());
			currSize = entry.getProgress();
			currPercent = entry.getPercent();
		} else {
			Utils.log(DownloadTask.class.getSimpleName(), "start==>" + "First log into history!");
		}

		downloadThread = new DownloadThread(context, this.entry, this);
		downloadThread.setPriority(Thread.MAX_PRIORITY);
		downloadThread.start();
	}

	@Override
	public synchronized void onProgressChanged(long length, int len) {
		currSize = length;
		double percent = 0;
		if (entry.getSize() != 0) {
			percent = currSize * 100.0 / entry.getSize();
			DecimalFormat df = new DecimalFormat("#.0");
			percent = Double.parseDouble(df.format(percent));
		}
		entry.setProgress(currSize);
		if (percent == 100.0d) {
			entry.setPercent(100);
		} else {
			entry.setPercent(percent);
		}

		if (percent > currPercent) {
			currPercent = percent;
			Message msg = handler.obtainMessage();
			handler.removeMessages(0);
			msg.what = 0;
			msg.obj = entry;
			handler.sendMessage(msg);
			DownloadDao.getInstance(context).newOrUpdate(entry);
		}

		// 计算下载速度
		if (System.currentTimeMillis() - lastTime > Constants.SPEED_CHECK_INTERVAL) {
			entry.setSpeed(intervalDownloadedSize
					/ (Constants.SPEED_CHECK_INTERVAL));
			lastTime = System.currentTimeMillis();
			intervalDownloadedSize = 0;
			DownloadDao.getInstance(context).newOrUpdate(entry);
		} else {
			intervalDownloadedSize += len;
		}

		Utils.log(DownloadTask.class.getSimpleName(),
				"onProgressChanged==>" + entry.getName() + "**"
						+ entry.getPercent() + "%**" + entry.getSpeed() + "k/s");
	}

	@Override
	public void onStatusChanged(DownloadStatus status) {

		if (status == DownloadStatus.cancel
				|| status == DownloadStatus.hijack) {
			entry.setProgress(0);
			entry.setPercent(0);
			FileUtils.deleteFile(entry.getPath());
			DownloadDao.getInstance(context).delete(entry.getUrl());
			Utils.log(DownloadTask.class.getSimpleName(),
					"onStatusChanged==>" + entry.getUrl() + " is calcled!");
		}

		if (status == DownloadStatus.done) {
			entry.setSpeed(0);
			entry.setProgress(entry.getSize());
			entry.setPercent(100);
		}

		if (status == DownloadStatus.pause) {
			entry.setSpeed(0);
		}

		/*********************** 处理网络异常 ***********************/
		if (status == DownloadStatus.timeout || status == DownloadStatus.neterror) {
			Map<String, DownloadTask> taskMap = DataChanger.getInstance().getDownloadingTasks();
			Iterator<String> iterator = taskMap.keySet().iterator();
			String key;
			while (iterator.hasNext()) {
				key = iterator.next();
				DownloadTask task = taskMap.get(key);
				if (task != null) {
					task.pause();
				}
				iterator.remove();
			}
		}

		entry.setStatus(status);
		DownloadDao.getInstance(context).newOrUpdate(entry);
		Message msg = handler.obtainMessage();
		msg.what = 1;
		msg.obj = entry;
		handler.sendMessage(msg);
		Utils.log(DownloadTask.class.getSimpleName(), "onStatusChanged:" + status);
	}

	public void cancel() {
		downloadThread.setStatus(DownloadStatus.cancel);
	}

	public void pause() {
		downloadThread.setStatus(DownloadStatus.pause);
	}

	public DownloadEntity getEntry() {
		return entry;
	}
}
