package gov.nist.androidsuite;

import android.os.Debug;
import android.os.Environment;

public class Val5 {
	/**
	 * val5.java 2013-06-04 1:06PM Reference executable for validating
	 * application profiling tools. val5: recursive function with one
	 * self-invocation.
	 * 
	 * With default values of FN1LOOP and FN2LOOP, the expected distribution of
	 * time is 100 % to cycfn, of which 33 % is in the first (top) invocation
	 * and 66 % is in the second (leaf) invocation.
	 * 
	 * Old (2013-03-08 10:34) Spin was for Windows + Intel Composer XE 2013 +
	 * Microsoft Visual Studio 2012. Language c99.
	 * 
	 * New Spin for Android + DDMS + Eclipse. Language Java.
	 */

	// Configurable FN1LOOP: how many busy-work iterations in top invocation.
	private long fn1loop = 250000;

	// Configurable FN2LOOP: how many busy-work iterations in leaf invocation.
	private long fn2loop = fn1loop * 2;

	public String Output = "";

	private long accumulator = 1;
	private double adder = 0;

	// / Method to start calling of functions
	public int Start(int repeat, long FN1LOOP, long FN2LOOP, int TraceBuffer) {
		if (FN1LOOP > 0) {
			fn1loop = FN1LOOP;
			fn2loop = fn1loop * 2;
		}
		if (FN2LOOP > 0) {
			fn2loop = FN2LOOP;
		}
		Debug.startMethodTracing(Environment.getExternalStorageDirectory()+"/Traces/ValFive" + Integer.toString(repeat),
				TraceBuffer);
		cycfn(false);
		Debug.stopMethodTracing();
		Output = "Accumulator: " + accumulator + "\n" + "Adder: " + adder;
		return 0;
	}

	// / Overload of the start function, if programmer just starts the gathering
	// process.
	public int Start() {
		// MainActivity.BufferToTrace is a variable being pass from the app
		// class,
		// if this class isn't available MainActivity.BufferToTrace default is
		// 8000000
		return Start(1, fn1loop, fn2loop, MainActivity.BufferToTrace);
	}

	private void cycfn(boolean leaf) {
		for (long looper = 0; looper < (leaf ? fn2loop : fn1loop); ++looper) {
			adder += Math.PI * 3;
			accumulator = (long) ((accumulator * 3) + adder);
		}
		if (!leaf) {
			cycfn(true);
		}
	}
}
