//
// BEGIN FLOCK GPL
//
// Copyright Flock Inc. 2005-2009
// http://flock.com
//
// This file may be used under the terms of the
// GNU General Public License Version 2 or later (the "GPL"),
// http://www.gnu.org/licenses/gpl.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// END FLOCK GPL
//

const FLOCK_STOPWATCH_CID        = Components.ID("{5499e4fd-60ab-4c39-aa6d-badd82e4dd39}");
const FLOCK_STOPWATCH_CLASSNAME  = "Flock Stop Watch";
const FLOCK_STOPWATCH_CONTRACTID = "@flock.com/stopwatch;1";

// ========================================================
// ========== BEGIN flockStopWatch class ==========
// ========================================================

function flockStopWatchMark(inMarkName, inMarkTime)
{
  this._markName = inMarkName;
  this._markTime = inMarkTime;
}

function flockStopWatch()
{
  this._logger = Components.classes['@flock.com/logger;1'].createInstance(Components.interfaces.flockILogger);
  this._logger.init('flockStopWatch');
  this._logger.info('Created Stop Watch Object');
  this._watches = new Array();
}

// BEGIN flockIStopWatch interface
flockStopWatch.prototype.start =
function flockStopWatch_start(nStopWatchName)
{
  this._stopWatchName = nStopWatchName;
  this._startTime = new Date();
  this._marks = new Array();
  this._logger.info("[" + this._stopWatchName + "] Start Time = " + this.timeToString(this._startTime));
}

flockStopWatch.prototype.stop =
function flockStopWatch_stop()
{
  var mark = 0;
  this._endTime = new Date();
  this._logger.info("[" + this._stopWatchName + "] Results for Stop Watch:");  
  for (markEntry = 0; markEntry < this._marks.length; markEntry++)
  {
    this._logger.info("[" + this._stopWatchName + "]  Mark (" + this._marks[markEntry]._markName + ") = " +
      (markEntry > 0 ?  this.getTimeDiff(this._marks[markEntry]._markTime,this._marks[markEntry-1]._markTime) + ", " : "") +
      this.getTimeDiff(this._marks[markEntry]._markTime,this._startTime));
  }
  this._logger.info("[" + this._stopWatchName + "]  Total Time = " + this.getTimeDiff(this._endTime,this._startTime));
}

flockStopWatch.prototype.mark =
function flockStopWatch_mark(nMarkName)
{
  var markTime = new flockStopWatchMark(nMarkName, new Date());
  var prevMarkTime = (this._marks.length > 0 ? this._marks[this._marks.length - 1]._markTime : this._startTime);
  
  this._marks.push(markTime);
  this._logger.info("[" + this._stopWatchName + "] Mark Time (" + nMarkName + ") = " + this.timeToString(markTime._markTime));    
}

// Internal functions
flockStopWatch.prototype.timeToString =
function flockStopWatch_timeToString(inDateTime)
{
  var outString = "";
  
  outString = outString + inDateTime.getHours();
  outString = outString + ":" + inDateTime.getMinutes();
  outString = outString + ":" + inDateTime.getSeconds();
  outString = outString + "." + inDateTime.getMilliseconds();
  
  return outString;  
}

flockStopWatch.prototype.getTimeDiff =
function flockStopWatch_getTimeDiff(endTime, startTime)
{
  var milliseconds = 0;
  var seconds = 0;
  var minutes = 0;
  var hours = 0;
   
  milliseconds = (endTime - startTime);
  if (milliseconds > 999) {
    seconds = Math.round(milliseconds / 1000);
    milliseconds = (milliseconds % 1000);
  }
  if (seconds > 59) {
    minutes = Math.round(seconds / 60);
    seconds = (seconds % 60);
  }
  if (minutes > 59) {
    hours = Math.round(minutes / 60);
    minutes = (minutes % 60);
  }

  return (hours + ":" + minutes + ":" + seconds + "." + milliseconds);
}

// END flockIStopWatch interface


// BEGIN nsISupports interface
flockStopWatch.prototype.QueryInterface =
function flockStopWatch_QueryInterface(aIID)
{
  if (!aIID.equals(Components.interfaces.nsISupports) &&
      //!aIID.equals(Components.interfaces.nsIClassInfo) &&
      !aIID.equals(Components.interfaces.flockIStopWatch))
  {
    throw Components.results.NS_ERROR_NO_INTERFACE;
  }
  return this;
}
// END nsISupports interface

// BEGIN nsIClassInfo interface
/*
flockStopWatch.prototype.flags = Components.interfaces.nsIClassInfo.THREADSAFE;
flockStopWatch.prototype.contractID = FLOCK_STOPWATCH_CONTRACTID;
flockStopWatch.prototype.classDescription = FLOCK_STOPWATCH_CLASSNAME;
flockStopWatch.prototype.implementationLanguage = Componets.interfaces.nsIProgrammingLanguage.JAVASCRIPT;

flockStopWatch.prototype.getInterfaces =
function flockStopWatch_getInterfaces(count)
{
    var interfaceList = [
      //Components.interfaces.nsIClassInfo,
    	Components.interfaces.nsISupports];
    count.value = interfaceList.length;
    return interfaceList;
}

flockStopWatch.prototype.getHelperForLanguage =
function flockStopWatch_getHelperForLanguage(count) 
{
  return null;
}
*/
// END nsIClassInfo interface


// ========== BEGIN XPCOM Module support ==========

// BEGIN flockflockStopWatchModule object
var flockStopWatchModule = new Object();

flockStopWatchModule.registerSelf =
function flockStopWatchModule_registerSelf(compMgr, fileSpec, location, type)
{
  compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  compMgr.registerFactoryLocation( FLOCK_STOPWATCH_CID, 
                                   FLOCK_STOPWATCH_CLASSNAME,
                                   FLOCK_STOPWATCH_CONTRACTID, 
                                   fileSpec, 
                                   location,
                                   type );
}

flockStopWatchModule.getClassObject =
function flockStopWatchModule_getClassObject(compMgr, cid, iid)
{
  if (!cid.equals(FLOCK_STOPWATCH_CID))
    throw Components.results.NS_ERROR_NO_INTERFACE;
  if (!iid.equals(Components.interfaces.nsIFactory))
    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  return flockStopWatchFactory;
}

flockStopWatchModule.canUnload =
function flockStopWatchModule_canUnload(compMgr)
{
  return true;
}
// END flockflockStopWatchModuleModule object


// BEGIN flockStopWatchFactory object
var flockStopWatchFactory = new Object();

flockStopWatchFactory.createInstance =
function flockStopWatchFactory_createInstance(outer, iid)
{
  if (outer != null) {
    throw Components.results.NS_ERROR_NO_AGGREGATION;
  }
  return (new flockStopWatch()).QueryInterface(iid);
}
// END flockStopWatchFactory object


// NS module entry point
function NSGetModule(compMgr, fileSpec) {
  return flockStopWatchModule;
}

// ========== END XPCOM module support ==========
