var tt = window.tt || {}; //application global


/*
 * Debug logging
 * 
 */

function deBugClog(args)
{

	//set these to log a module
	var showMods = [
        ["animation",false],
		["anim",false],
		["ws", false],
		["ws-anim", false],
		["timesel",false],
		["toy",false],
		["3dmap",false]
		 ];
	if(tt.cg.alpha === "1")
	{
		
		for(var x in showMods)
		{
			
			if(showMods[x][0] === arguments[0] && showMods[x][1] === true)
			{
				
				
				for(var i = 0; i < arguments.length; i++)
				{
					console.log(arguments[i]);
				}
				/*
				var con = "console.log(";
				for(var i = 1; i < arguments.length; i++)
				{
					con += (i > 1 ? "," : "") 
						+ (typeof arguments[i] === "string" ? "'" :"")
						+ arguments[i]
						+ (typeof arguments[i] === "string" ? "'" : "");
				}			
				con += ")";
				//alert(con);
				eval(con);*/
				
			}
		}
	}
}

/*
 * mouseupdownmove with drag
 * 
 */


/*
 * Harmes-Diaz Interface Constructor.
 */



var Interface = function(name, methods) {
    if(arguments.length != 2) {
        throw new Error("Interface constructor called with " + arguments.length
          + "arguments, but expected exactly 2.");
    }
    
    this.name = name;
    this.methods = [];
    for(var i = 0, len = methods.length; i < len; i++) {
        if(typeof methods[i] !== 'string') {
            throw new Error("Interface constructor expects method names to be " 
              + "passed in as a string.");
        }
        this.methods.push(methods[i]);        
    }    
};    

// Static class method.

Interface.ensureImplements = function(object) {
    if(arguments.length < 2) {
        throw new Error("Function Interface.ensureImplements called with " + 
          arguments.length  + "arguments, but expected at least 2.");
    }

    for(var i = 1, len = arguments.length; i < len; i++) {
        var interface = arguments[i];
        if(interface.constructor !== Interface) {
            throw new Error("Function Interface.ensureImplements expects arguments "   
              + "two and above to be instances of Interface.");
        }
        
        for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) {
            var method = interface.methods[j];
            if(!object[method] || typeof object[method] !== 'function') {
                throw new Error("Function Interface.ensureImplements: object " 
                  + "does not implement the " + interface.name 
                  + " interface. Method " + method + " was not found.");
            }
        }
    } 
};


/*
 * Control handling
 */

function AddSelectOption(selectObj, text, value, isSelected) 
{

	if (selectObj != null && selectObj.options != null)
	{
		selectObj.options[selectObj.options.length] = 
				new Option(text, value, false, isSelected);
	}
}


function catchEnterKey(e, fireFunction)
{
	var result = checkEnter(e,13); //checks if code is 13
	if(!result)
	{
		fireFunction();
	}
	return result;
}

function checkEnter(e,charCode)
{ //e is event object passed from function invocation
	var characterCode; //literal character code will be stored in this variable

	if(e && e.which){ //if which property of event object is supported (NN4)
		e = e;
		characterCode = e.which; //character code is contained in NN4's which property
	}
	else
	{
		e = event;
		characterCode = e.keyCode; //character code is contained in IE's keyCode property
	}

	if(characterCode == charCode)
	{ 
		//if generated character code is equal to ascii 13 (if enter key)
		return false;
	}
	else
	{
		return true;
	}

}

function getElementsByClass(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp('(^|\\\\s)'+searchClass+'(\\\\s|$)');
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}


/*
 * String handling
 * 
 */

function repeat(s, n){
    var a = [];
    while(a.length < n){
        a.push(s);
    }
    return a.join('');
}

String.prototype.trim = function () {
	return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
};


/*
 * Resizing and dimension handling
 * 
 */

function clientCoords() 
{
	var dimensions = {width: 0, height: 0};
	if (document.documentElement) {
		dimensions.width = document.documentElement.offsetWidth;
		dimensions.height = document.documentElement.offsetHeight;
	} else if (window.innerWidth && window.innerHeight) {
		dimensions.width = window.innerWidth;
		dimensions.height = window.innerHeight;
	}
	return dimensions;
}


function show(newItem, on)
{
	var item = document.getElementById(newItem);
	if(on)
	{
		//$(newItem).css('display','block');
		item.style.display="block";
	}
	else
	{
		//$(newItem).css('display','none');
		item.style.display="none";
	}
}


/*
 * Crockford JSON parser
 * 
 */



// The following block implements the string.parseJSON method
(function (s) {
  // This prototype has been released into the Public Domain, 2007-03-20
  // Original Authorship: Douglas Crockford
  // Originating Website: http://www.JSON.org
  // Originating URL    : http://www.JSON.org/JSON.js

  // Augment String.prototype. We do this in an immediate anonymous function to
  // avoid defining global variables.

  // m is a table of character substitutions.

  var m = {
    '\b': '\\b',
    '\t': '\\t',
    '\n': '\\n',
    '\f': '\\f',
    '\r': '\\r',
    '"' : '\\"',
    '\\': '\\\\'
  };

  s.parseJSON = function (filter) {

    // Parsing happens in three stages. In the first stage, we run the text against
    // a regular expression which looks for non-JSON characters. We are especially
    // concerned with '()' and 'new' because they can cause invocation, and '='
    // because it can cause mutation. But just to be safe, we will reject all
    // unexpected characters.

    try {
      if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.
        test(this)) {

          // In the second stage we use the eval function to compile the text into a
          // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
          // in JavaScript: it can begin a block or an object literal. We wrap the text
          // in parens to eliminate the ambiguity.

          var j = eval('(' + this + ')');

          // In the optional third stage, we recursively walk the new structure, passing
          // each name/value pair to a filter function for possible transformation.

          if (typeof filter === 'function') {

            function walk(k, v) {
              if (v && typeof v === 'object') {
                for (var i in v) {
                  if (v.hasOwnProperty(i)) {
                    v[i] = walk(i, v[i]);
                  }
                }
              }
              return filter(k, v);
            }

            j = walk('', j);
          }
          return j;
        }
      } catch (e) {

      // Fall through if the regexp test fails.

      }
      throw new SyntaxError("parseJSON");
    };
  }
) (String.prototype);
// End public domain parseJSON block




/*
 * Date handling
 * 
 * 
 */

function dateToISO(da,fmt,isDisplay,isUTC)
{
	var result = "";
	//da =  a Date Object
	if(isUTC){
		dy = da.getUTCFullYear();	// Get full year (as opposed to last two digits only)
		dm = da.getUTCMonth() + 1;	// Get month and correct it (getMonth() returns 0 to 11)
		dd = da.getUTCDate();	// Get date within month
		dh = da.getUTCHours();
		dmin = da.getUTCMinutes();
	}else{
		dy = da.getFullYear();	// Get full year (as opposed to last two digits only)
		dm = da.getMonth() + 1;	// Get month and correct it (getMonth() returns 0 to 11)
		dd = da.getDate();	// Get date within month
		dh = da.getHours();
		dmin = da.getMinutes();
	}
	
	if ( dy < 1970 ) dy = dy ;
	
	ys = new String(dy);	// Convert year, month and date to strings
	ms = new String(dm);	 
	ds = new String(dd);	 
	hs = new String(dh);
	mins = new String(dmin);
	
	
	if ( ms.length == 1 ) ms = "0" + ms;	// Add leading zeros to month and date if required
	if ( ds.length == 1 ) ds = "0" + ds;	
	if ( hs.length == 1 ) hs = "0" + hs;
	if ( mins.length == 1 ) mins = "0" + mins;
		
	if(fmt==="YYYY")
	{
		result = ys;
	}
	else if(fmt==="YYYY-mm")
	{
		result = ys + "-" + ms;
	}
	else if(fmt==="DD")
	{
		result = ms + "-" + ds;
	}
	else if(fmt==="HH")
	{
		result = hs + ":00";
	}
	else if(fmt==="MM")
	{
		result = mins;
	}
	else if(fmt==="YYYY-mm-DDThh:MM")
	{
		result = ys + "-" + ms + "-" + ds + "T" + hs + ":" + mins;
	}
	else if(fmt==="YYYY-mm-DD")
	{
		result = ys + "-" + ms + "-" + ds;
	}
	else
	{
		result = ys + "-" + ms + "-" + ds;
	}
		
	if(result.indexOf("-") === 0){ //we have a minus sign
		if(isDisplay){
			result = result.substring(1)  + " BC";
		}
	}

	return result;
}

function isoToDate(da)
{

	//da =  an iso Date String
	//1997-07-16T19:20
	str = da.split("-");
	var yr, mo, dy, rest;
	if(da.substring(0,1)=="-") //BC
	{
		yr = "-" + str[1];
		mo = str[2];
		rest = str[3];
	}
	else
	{
		yr = str[0];
		mo = str[1];
		rest = str[2];
	}
	if(rest.indexOf("T")>=0) //there is time
	{
		dy = rest.substring(0,rest.indexOf("T"));
		rest = rest.substring(rest.indexOf("T")+1); //skip the T
		str = rest.split(":");
		hr = str[0];
		min = str[1];
	}
	else
	{
		dy = rest;
		hr = "00";
		min = "00";
	}

	var myDate = new Date(2010,1,11,hr,min); // arbitrary
	myDate.setFullYear(yr,mo,dy);
	return myDate;
}

//function mouseUpAfterDrag(e) {
//	 
//    /* You can record the starting position with */
//    var start_x = e.pageX;
//    var start_y = e.pageY;
////	var offset_x;
////	var offset_y;
//	
//    $().mousemove(function(e) {
//        /* And you can get the distance moved by */
//        offset_x = e.pageX - start_x;
//        offset_y = e.pageY - start_y;
//    });
// 
//    $().one('mouseup', function() {
//        alert("This will show after mousemove and mouse released.");
//        if(offset_x && offset_y) {
//			tt.timesel.DragLimits(offset_x,offset_y);
//		} else { 
//
//		}
//        $().unbind();
//        $('#timeCircleBox').mousedown(mouseUpAfterDrag);
//    });
// 
//    // Using return false prevents browser's default,
//    // often unwanted mousemove actions (drag & drop)
//    return false;
//}
