package org.cocos2d.support;

import org.cocos2d.config.ccConfig;
import org.cocos2d.config.ccMacros;
import org.cocos2d.utils.CCFormatter;

/**
 * @addtogroup global
 * @{
 */

public class CCProfiling {

	/* set to NO the categories that you don't want to profile */
	public static boolean kCCProfilerCategorySprite = false;
	public static boolean kCCProfilerCategoryBatchSprite = false;
	public static boolean kCCProfilerCategoryParticles = false;

	public static void CC_PROFILER_DISPLAY_TIMERS() {
		if(ccConfig.CC_ENABLE_PROFILERS) {
			CCProfiler.sharedProfiler().displayTimers();
		}
	}

	public static void CC_PROFILER_PURGE_ALL() {
		if(ccConfig.CC_ENABLE_PROFILERS) {
			CCProfiler.sharedProfiler().releaseAllTimers();
		}
	}

	public static void CC_PROFILER_START(String __name__) {
		if(ccConfig.CC_ENABLE_PROFILERS) {
			CCProfilingBeginTimingBlock(__name__);
		}
	}

	public static void CC_PROFILER_STOP(String __name__) {
		if(ccConfig.CC_ENABLE_PROFILERS) {
			CCProfilingEndTimingBlock(__name__);
		}
	}

	public static void CC_PROFILER_RESET(String __name__) {
		if(ccConfig.CC_ENABLE_PROFILERS) {
			CCProfilingResetTimingBlock(__name__);
		}
	}

	public static void CC_PROFILER_START_CATEGORY(boolean __cat__, String __name__) {
		if(ccConfig.CC_ENABLE_PROFILERS) {
			if(__cat__) CCProfilingBeginTimingBlock(__name__);
		}
	}

	public static void CC_PROFILER_STOP_CATEGORY(boolean __cat__, String __name__) {
		if(ccConfig.CC_ENABLE_PROFILERS) {
			if(__cat__) CCProfilingEndTimingBlock(__name__);
		}
	}

	public static void CC_PROFILER_RESET_CATEGORY(boolean __cat__, String __name__) {
		if(ccConfig.CC_ENABLE_PROFILERS) {
			if(__cat__) CCProfilingResetTimingBlock(__name__);
		}
	}

	public static void CC_PROFILER_START_INSTANCE(int __id__, String __name__) {
		if(ccConfig.CC_ENABLE_PROFILERS) {
			CCProfilingBeginTimingBlock(CCFormatter.format("%08X - %s", __id__, __name__));
		}
	}

	public static void CC_PROFILER_STOP_INSTANCE(int __id__, String __name__) {
		if(ccConfig.CC_ENABLE_PROFILERS) {
			CCProfilingEndTimingBlock(CCFormatter.format("%08X - %s", __id__, __name__));
		}
	}

	public static void CC_PROFILER_RESET_INSTANCE(int __id__, String __name__) {
		if(ccConfig.CC_ENABLE_PROFILERS) {
			CCProfilingResetTimingBlock(CCFormatter.format("%08X - %s", __id__, __name__));
		}
	}

	/** CCProfiler
	 * cocos2d builtin profiler.
	 * 
	 * To use it, enable set the CC_ENABLE_PROFILERS=1 in the ccConfig.h file
	 */
	public static class CCProfiler {
		private static final String TAG = CCProfiler.class.getSimpleName();

		public static CCProfiler sharedProfiler() {
			synchronized(CCProfiler.class) {
				if(g_sSharedProfiler == null) {
					g_sSharedProfiler = new CCProfiler();
					g_sSharedProfiler.init();
				}

				return g_sSharedProfiler;
			}
		}

		/** display the timers */
		public void displayTimers() {
/* TODO
			CCDictElement pElement;
			CCDICT_FOREACH(m_pActiveTimers, pElement)
			{
				CCProfilingTimer timer = (CCProfilingTimer)pElement.getObject();
				ccMacros.CCLOG(TAG, timer.description());
			}
*/
		}

		public boolean init() {
// TODO			m_pActiveTimers = new CCDictionary();
			return true;
		}

		/** Creates and adds a new timer */
		public CCProfilingTimer createAndAddTimerWithName(String timerName) {
			CCProfilingTimer t = new CCProfilingTimer();
			t.initWithName(timerName);
// TODO			m_pActiveTimers.setObject(t, timerName);

			return t;
		}

		/** releases a timer */
		public void releaseTimer(String timerName) {
// TODO			m_pActiveTimers.removeObjectForKey(timerName);
		}

		/** releases all timers */
		public void releaseAllTimers() {
// TODO			m_pActiveTimers.removeAllObjects();
		}

// TODO		public CCDictionary m_pActiveTimers;

		private static CCProfiler g_sSharedProfiler;
	};

	public static class CCProfilingTimer {

		public boolean initWithName(String timerName) {
			m_NameStr = timerName;
			numberOfCalls = 0;
			m_dAverageTime = 0.0;
			totalTime = 0.0;
			minTime = 10000.0;
			maxTime = 0.0;
			m_sStartTime = System.currentTimeMillis();

			return true;
		}

		public String description() {
			return CCFormatter.format("%s: avg time, %fms", m_NameStr, m_dAverageTime);
		}

		public long getStartTime() {
			return m_sStartTime;
		}

		public void setAverageTime(double value) {
			m_dAverageTime = value;
		}

		public double getAverageTime() {
			return m_dAverageTime;
		}

		/** resets the timer properties */
		public void reset() {
			numberOfCalls = 0;
			m_dAverageTime = 0;
			totalTime = 0;
			minTime = 10000;
			maxTime = 0;
			m_sStartTime = System.currentTimeMillis();
		}

		public String m_NameStr;
		public long m_sStartTime;
		public double m_dAverageTime;
		public double minTime;
		public double maxTime;
		public double totalTime;
		public int numberOfCalls;
	};

	public static void CCProfilingBeginTimingBlock(String timerName) {
/* TODO
		CCProfiler p = CCProfiler.sharedProfiler();
		CCProfilingTimer timer = (CCProfilingTimer)p.m_pActiveTimers.objectForKey(timerName);
		if(timer == null) {
			timer = p.createAndAddTimerWithName(timerName);
		}

		timer.m_sStartTime = System.currentTimeMillis();

		timer.numberOfCalls++;
*/
	}

	public static void CCProfilingEndTimingBlock(String timerName) {
/* TODO
		CCProfiler p = CCProfiler.sharedProfiler();
		CCProfilingTimer timer = (CCProfilingTimer)p.m_pActiveTimers.objectForKey(timerName);

		assert timer != null : "CCProfilingTimer  not found";

		long currentTime = System.currentTimeMillis();

		double duration = CCTime.timersubCocos2d(timer.m_sStartTime, currentTime);

		// milliseconds
		timer.m_dAverageTime = (timer.m_dAverageTime + duration) / 2.0f;
		timer.totalTime += duration;
		timer.maxTime = Math.max(timer.maxTime, duration);
		timer.minTime = Math.min(timer.minTime, duration);
*/
	}

	public static void CCProfilingResetTimingBlock(String timerName) {
/* TODO
		CCProfiler p = CCProfiler.sharedProfiler();
		CCProfilingTimer timer = (CCProfilingTimer)p.m_pActiveTimers.objectForKey(timerName);

		assert timer != null : "CCProfilingTimer not found";

		timer.reset();
*/
	}
}

// end of global group
/// @}
