package hh.dejsem.fm;

import android.os.Bundle;

/**
 * drží a poskytuje údaje o velikosti file/directory/batch a o průběhu přenosu
 * <p>
 * ● metody jsou synchronizovány, protože položky running... jsou průběžně aktualizovány
 *      metodami síťových přenosů běžících ve zvláštních vláknech ve třídě LongAsyncTask
 *      a průběžně z nich čerpají v průběhu přenosů třídy Title a ProgressMonitor
 */
public class EntitySize {
	static final int dirSize = 4096;

	static final String TARGET_SIZE_KEY = "TARGET_SIZE_KEY";
	static final String TARGET_FNUM_KEY = "TARGET_FNUM_KEY";
	static final String TARGET_DNUM_KEY = "TARGET_DNUM_KEY";

	static final String RUNNING_SIZE_KEY = "RUNNING_SIZE_KEY";
	static final String RUNNING_FNUM_KEY = "RUNNING_FNUM_KEY";
	static final String RUNNING_DNUM_KEY = "RUNNING_DNUM_KEY";
	static final String PCT_KEY = "PCT_KEY";
	static final String STALLED_KEY = "STALLED_KEY";
	static final String FN_KEY = "FN_KEY";

	private long targetSize = 0;    // incremented by file targetSize during batch transfer
	private int targetFnum = 0;
	private int targetDnum = 0;
	private long runningSize = 0;   // incremented by buff targetSize during current file transfer; after finishing curr file, runningSize == targetSize
	private long lastRunningSize = 0;
	private long stallTs = System.currentTimeMillis();
	private int runningFnum = 0;
	private int runningDnum = 0;
	private String fn = ""; 	    // file name of file currently transferred in a batch
	/* ----------------------------------------------------------*/

	public EntitySize() {}

	public EntitySize(EntitySize es) { add(es); }

	public EntitySize(long targetSize, int targetFnum, int targetDnum) {
		this.targetSize = targetSize;
		this.targetFnum = targetFnum;
		this.targetDnum = targetDnum;
	}

	public synchronized void setTargetSize(long targetSize) { this.targetSize = targetSize; }

	/*synchronized void setFnum(int fnum) { this.fnum = fnum; }*/

	synchronized void add(EntitySize es) {
		targetSize += es.targetSize;
		targetFnum += es.targetFnum;
		targetDnum += es.targetDnum;
		runningSize += es.runningSize;
		runningFnum += es.runningFnum;
		runningDnum += es.runningDnum;
		fn = es.fn;
	}

	synchronized void addTargetFile(long size) {
		targetSize += size;
		targetFnum++;
	}

	synchronized void addTargetDir() {
		targetSize += dirSize;
		targetDnum++;
	}

	/*synchronized void incrS(int incr) { runningSize += incr; }*/

	public synchronized void incrR(int incr, String fn) {
		runningSize += incr;
		this.fn = fn;
	}

	public synchronized void incrF() {
		runningFnum++;
	}

	public synchronized void incrD(String dn) {
		runningDnum++;
		runningSize += dirSize;
		this.fn = dn;
	}

	synchronized EntitySize zero() {
		runningSize = 0;
		runningFnum = 0;
		runningDnum = 0;
		runningSize = 0;
		return this;
	}

	public synchronized long getTargetSize() { return targetSize; }

	synchronized int getTargetFnum() { return targetFnum; }

	synchronized int getTargetDnum() { return targetDnum; }

	public synchronized long getRunningSize() { return runningSize; }

	synchronized String getFn() { return fn; }

	public synchronized int getPct() { return (targetSize == 0 ? 0 : (int)(100 * runningSize / targetSize)); }

	synchronized Bundle getTarget() {
		Bundle b = new Bundle();
		b.putLong(TARGET_SIZE_KEY, targetSize);
		b.putInt(TARGET_FNUM_KEY, targetFnum);
		b.putInt(TARGET_DNUM_KEY, targetDnum);
		return b;
	}

	synchronized Bundle getStatus() {
		boolean stalled = false;
		if(System.currentTimeMillis() - stallTs > 10*1000) {
			stalled = lastRunningSize == runningSize;
			lastRunningSize = runningSize;
			stallTs = System.currentTimeMillis();
		}
		Bundle b = new Bundle();
		b.putLong(TARGET_SIZE_KEY, targetSize);
		b.putLong(RUNNING_SIZE_KEY, runningSize);
		b.putInt(RUNNING_FNUM_KEY, runningFnum);
		b.putInt(RUNNING_DNUM_KEY, runningDnum);
		b.putString(FN_KEY, fn);
		b.putInt(PCT_KEY, getPct());
		b.putBoolean(STALLED_KEY, stalled);
		return b;
	}

	/*@Override
	synchronized public String toString() {
		return "(fn=" + fn + ", targetSize=" + targetSize + ", fnum=" + fnum + ", dnum=" + dnum + ", runningSize=" + runningSize + ")";
	}*/
}

