/**
  *  @projectDescription
  *  <p>A collection of global utilities</p>
  *
  *  @author			Miraversa
  *  @version			1.0
  *
  */

/////// Session Id Functions Begin ////////////////////
function getSessionId(){
	// Get a sessionid, cookie, qs, generate
	var ttsid = "";	// Omniture session id
	// check cookie
	ttsid = getCookie("ttsid");
	if ((ttsid == "") || (ttsid == null)){
		// check url querystring
		var fullPageUrl = window.location.search;
		ttsid = getQueryStringValue(fullPageUrl, "ttsid");
	}
	if ((ttsid == "") || (ttsid == null)){
		// generate sessionid from guid
		ttsid = getGuid(20);
	}
	return ttsid;
}
function storeSessionId(ttsid){
	var expireDays = 220;
	var expireStamp = new Date(new Date().getTime() + expireDays * 24 * 3600 * 1000);
	setCookie("ttsid", ttsid, expireStamp, "/",sessionDomain);
}
function initSessionId(){
	var ttsid = getSessionId();
	storeSessionId(ttsid);
	return ttsid;
}
function getGuid(n){
	var t = new Date().getTime()+""; //milliseconds since 1 January 1970
	n = n - t.length;
	var g = t;
	for(var i = 0; i < n; i++) {
		g += Math.floor(Math.random() * 0xF).toString(0xF) + (i == 8 || i == 12 || i == 16 || i == 20 ? "-" : "");
	}
	return g;
}
/////// Session Id Functions End /////////////////
/////// Session Id Main Start ////////////////////
var sessionDomain=".intuit.com";
var ttsid = initSessionId();
var today = new Date();
var timeString = today.getTime();
var s_prop8 = ttsid;
/////// Session Id Main End ////////////////////

function getQueryStringValue(sourceUrl, key) {
  var u = sourceUrl;
  var parmValue = "";
  u = u.slice(1);
  parms = u.split("&");
  var parmArray = [];
  for ( var i = 0; i < parms.length; i++){
    parmArray.push(parms[i].split("="));
  }
  for (var i=0;i<parmArray.length; i++) {
    if (parmArray[i][0] == key) {
      parmValue = parmArray[i][1];
    }
  }
  return parmValue;
}

// Cookie management
function getCookie(name) {
	var dc = document.cookie;
	var prefix = name + "=";
	var begin = dc.indexOf("; " + prefix);
	if (begin == -1) {
		begin = dc.indexOf(prefix);
		if (begin != 0) return null;
	} else begin += 2;
	var end = document.cookie.indexOf(";", begin);
	if (end == -1) end = dc.length;
	return unescape(dc.substring(begin + prefix.length, end));
}

function setCookie(name, value, expires, path, domain, secure) {
	var curCookie = name + "=" + escape(value) +
	((expires) ? "; expires=" + expires.toGMTString() : "") +
	((path) ? "; path=" + path : "") +
	((domain) ? "; domain=" + domain : "") +
	((secure) ? "; secure" : "");
	document.cookie = curCookie;	
}

//END TT


var debug       = new oDebug(true,"div","debug");
var system      = new oSystem();
var oJSON       = function(content){};  // The JSON Object's handle. Provided that the JSON content callback is referenced as oJSON().

includeJS=function(url,onload,allowCache){
	url=allowCache?url:url+'&nocache='+Math.random();
	url=url.split('?').length>1?url:url.replace(/\&/,'?');
	onload=typeof onload=="function"?onload:function(){};
	var js=document.createElement('script');
	js.setAttribute('src',url);
	js.addEventListener && function(){js.addEventListener('load',onload,false)}();
	js.onreadystatechange=function(){this.readyState=='complete' && onload.call()};
	document.getElementsByTagName('head').item(0).appendChild(js);
};

/**
* Include a JavaScript file dynamically
* include_js("http://api.search.yahoo.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=texas&results=2&output=json",alert("ready"));
*
* @constructor
* @param {String} file The file to include.
* @param {String} callback The name of the function to call when the file has loaded completely
* @return {String} The 
*/
include_js = (function(){

    var uid = 0;

    var remove = function(id){
        var head = document.getElementsByTagName('head')[0];
        head.removeChild( document.getElementById('jsInclude_'+id) );
    };

    return function(file,callback){

        var callback;
        var id = ++uid;
        var head = document.getElementsByTagName('head')[0];
        var js = document.createElement('scr'+'ipt');
            js.setAttribute('type','text/javascript');
            js.setAttribute('src',file);
            js.setAttribute('id','jsInclude_'+uid);

        if(document.all)
            js.onreadystatechange = function(){
            if(js.readyState == "complete"){ callback(id);remove(id); }
            };
        else
            js.onload = function(){
            callback(id); remove(id);
            };
        head.appendChild(js);
        return uid;
    };
})();


/**
* Include a CSS file dynamically
* include_css("assets/style/screen.css");
*
* @param String file = the file to include.
**/
include_css = (function(){

    var uid = 0;

    return function(file){

        var callback;
        var id = ++uid;
        var head = document.getElementsByTagName('head')[0];
        var css = document.createElement('link');
            css.setAttribute('rel', 'stylesheet');
            css.setAttribute('type', 'text/css');
            css.setAttribute('href', file);
            css.setAttribute('id','cssInclude_'+uid);

        head.appendChild(css);
        return uid;
    };
})();


/**
* Include a file dynamically using ajax
*
* ajax.setVar("varname","varvalue");
* var content = include_ajax("http://127.0.0.1/_codelibrary/servervars.asp","post","debug");
*
* @param String file = the file to include.
* @param String method = GET|POST
* @param String e = the id of document element to send the output to
*
* @return String file = the xml response string.
**/


function include_ajax(file,method,e){

	window.ajax = new sack();
	ajax.requestFile = "http://127.0.0.1/_codelibrary/servervars.asp";
	ajax.method = "post";
    ajax.element = e;
	ajax.runAJAX();

}

/**
* Transform an XML file with an XSLT
* transform("assets/xsl/test-json.xml","assets/xsl/xml2json.xslt");
*
* @param String source = the source xml file.
* @param String stylesheet = the xslt stylesheet.
**/

function transform(source,stylesheet){

    if(document.implementation && document.implementation.createDocument)
    {
    // FF
    var xsltProcessor = new XSLTProcessor();
    // Load XSL
    var xsl = new XMLHttpRequest();
        xsl.open("GET", stylesheet, false);
        xsl.send(null);

        xsltProcessor.importStylesheet(xsl.responseXML);

    // Load XML
        xml = new XMLHttpRequest();
        xml.open("GET", source, false);
        xml.send(null);

        return xsltProcessor.transformToFragment(xml.responseXML, document);


    } else if(window.ActiveXObject){
    // IE
    // Load XML
        xml = new ActiveXObject("MSXML2.DOMDocument");
        xml.async = false
        xml.load(source)

    // Load XSL
        xsl = new ActiveXObject("MSXML2.DOMDocument");
        xsl.async = false
        xsl.load(stylesheet)

        return xml.transformNode(xsl);

    }else{
    // Browser unknown
        return "Browser unknown";
    }
}

/************************************************************************************************************
* Utility functions
************************************************************************************************************/

/**
* Collect DOM elements by Class Name
*
* var formlabel = getElementsByClassName("ms-formlabel",document.getElementById("content"));
* alert("length:" + formlabel.length + " " + formlabel[0].innerText);
*
* @param String classname = the name of the class to collect
* @param Object rootNode = the node to begin with, defaults to "document".
**/
function getElementsByClassName(classname, rootNode){

    rootNode = rootNode?rootNode:document;

    if(rootNode.getElementsByTagName){
         var els = rootNode.getElementsByTagName("*");
         end = new Array();

         for(var i=0; i<els.length; i++){
              if(els[i].className){
              document.write(els[i].className);
                   if(els[i].className==classname){
                       end[end.length] = els[i];
                   }
              }
         }
         return end;
    }else{return false;}
}


/**
* Collect DOM elements by Attribute value
* Useful is using custom attributes
*
* var formbody = getElementsByAttribute("id","content");
* alert("length:" + formbody.length + " " + formbody[0].innerText);
*
* @param String attributeName = the name of the attribute to collect
* @param String attributeValue = the value of the attribute to collect
* @param Object rootNode = the node to begin with, defaults to "document".
**/
function getElementsByAttribute(attributeName, attributeValue, rootNode){

    rootNode = rootNode?rootNode:document;

    if(rootNode.getElementsByTagName){
        var els = rootNode.getElementsByTagName("*");
        var end = new Array();

        for(var i=0; i<els.length; i++){
            if(els[i].getAttribute(attributeName)){
               if(els[i].getAttribute(attributeName) == attributeValue){
                   end[end.length] = els[i];
               }
            }
        }
        return end;
    }else{return false;}
}



/**
* Collect DOM element by condition
* The condition is in the form of a function
*
* var helloElms = getElementsByCondition(function(el){return el.className.indexOf('hello')>-1})
*
* You can also perform an operation on an element at the same time.
*
* var hidden = getElementsByCondition(
* function(el){if(el.className=='hiders'){el.style.display='none';return el}}
* );
*
* @param {String} condition The id of the element to output the data into
* @param {Object} container The node to begin with, defaults to "document".
**/
function getElementsByCondition(condition,container)
{
    container = container*!document;
    var all = container.all*!container.getElementsByTagName('*');
    var arr = [];
    
    for(var i=0;i<all.length;i++){
        var elm = all[i];
        if(condition(elm,i));
        arr[arr.length] = elm ;
    }

    return arr;
}


/**
* System object system.out is to display content in a particular document element
* system.out("debug","<p>Now is the time for all good men to come to the aid of the country</p>");
*
* @param {String} e The id of the element to output the data into
* @param {String} s The string of text to output.
**/
function oSystem(){

    this.out = function(e,s){

            if(document.getElementById(e)){ // Does the element exist?
                document.getElementById(e).innerHTML = s;
            }else{
                var body = document.getElementsByTagName('body')[0];
                var div = document.createElement('div');
                    div.setAttribute('id', e);
                    body.appendChild(div);
            };
    };
};

/**
* Export to MS Word or MS Excel
* exportData('excel','center-in',document.getElementById('reportTitle').innerText);
*
* @param String type = the type of document to generate (doc|xls).
* @param String id = the id of the element to use as the data source for the generated document.
* @param String title = the file to include.
**/
function exportData(type, id, title){
    // DOC=application/ms-word
    // XLS=application/ms-excel
    var cssXls = '<style>BODY { 	margin-top:0em; 	margin-left:0em; 	FONT-FAMILY: helvetica, arial, geneva, sans-serif; 	BACKGROUND-COLOR: #FFFFFF; 	font-size:11px; 	FONT-WEIGHT: normal; 	color: #000000; 	margin-right: 0em; 	margin-bottom: 0em; 	background-repeat: repeat; } TABLE { 	margin-left:auto; 	margin-right:auto; 	empty-cells:show; 	border-style:hidden; 	border:0px; } .headingTitle { 	font-family: helvetica, arial, geneva, sans-serif; 	color:#000; 	font-size:11px; 	font-weight:bold; 	background-color: #A5C3DE; } .link { 	font-family: helvetica, arial, geneva, sans-serif; 	color:#000; 	font-size:11px; 	font-weight:normal; 	text-decoration: underline: nowrap; } .table { 	font-family: Arial, Helvetica, sans-serif; 	font-size: 11px; } .tableHeading { 	font-family: helvetica, arial, geneva, sans-serif; 	color:#000000; 	font-size:11px; 	font-weight:bold; 	background-color: #CCCCCC; 	height: auto ; 	text-decoration: none; } .dataRow1 { 	font-family: helvetica, arial, geneva, sans-serif; 	color:#000; 	font-size:11px; 	font-weight:normal; 	background-color: #FFF; 	padding-bottom: 2px; } .dataRow2 { 	font-family: helvetica, arial, geneva, sans-serif; 	color:#000000; 	font-size:11px; 	font-weight:normal; 	background-color: #A6C1DA; 	padding-bottom: 2px; } PRE { 	margin-top: 0em; 	margin-left: 0em; 	FONT-FAMILY: "Courier New", Courier, monospace; 	BACKGROUND-COLOR: #FFFFFF; 	font-size: 10px; 	FONT-WEIGHT: normal; 	color: #000000; 	margin-right: 0em; 	margin-bottom: 0em; } </style>';
    var cssDoc = '<style>BODY { 	margin-top:0em; 	margin-left:0em; 	FONT-FAMILY: helvetica, arial, geneva, sans-serif; 	BACKGROUND-COLOR: #FFFFFF; 	font-size:11px; 	FONT-WEIGHT: normal; 	color: #000000; 	margin-right: 0em; 	margin-bottom: 0em; 	background-repeat: repeat; } TABLE { 	margin-left:auto; 	margin-right:auto; 	empty-cells:show; 	border-style:hidden; 	border:0px; } .headingTitle { 	font-family: helvetica, arial, geneva, sans-serif; 	color:#000; 	font-size:11px; 	font-weight:bold; 	background-color: #A5C3DE; } .link { 	font-family: helvetica, arial, geneva, sans-serif; 	color:#000; 	font-size:11px; 	font-weight:normal; 	text-decoration: underline: nowrap; } .table { 	font-family: Arial, Helvetica, sans-serif; 	font-size: 11px; } .tableHeading { 	font-family: helvetica, arial, geneva, sans-serif; 	color:#000000; 	font-size:11px; 	font-weight:bold; 	background-color: #CCCCCC; 	height: auto ; 	text-decoration: none; } .dataRow1 { 	font-family: helvetica, arial, geneva, sans-serif; 	color:#000; 	font-size:11px; 	font-weight:normal; 	background-color: #FFF; 	padding-bottom: 2px; } .dataRow2 { 	font-family: helvetica, arial, geneva, sans-serif; 	color:#000000; 	font-size:11px; 	font-weight:normal; 	background-color: #A6C1DA; 	padding-bottom: 2px; } PRE { 	margin-top: 0em; 	margin-left: 0em; 	FONT-FAMILY: "Courier New", Courier, monospace; 	BACKGROUND-COLOR: #FFFFFF; 	font-size: 12px; 	FONT-WEIGHT: normal; 	color: #000000; 	margin-right: 0em; 	margin-bottom: 0em; } P.breakhere {page-break-before: always} </style>';
    var isExcel= (type.toLowerCase()=="excel")?true:false;

    contentType = (isExcel)?"application/ms-excel":"application/ms-word";
    contentExt  = (isExcel)?"xls":"doc";
    css         = (isExcel)?cssXls:cssDoc;

    var sOption = "toolbar=yes,location=no,directories=yes,status=yes,menubar=yes,scrollbars=yes,width=750,height=600,left=100,top=25";
    //  P.breakhere {page-break-before: always}
    var pageBreak = '<P class="breakhere">';
    var winHTML = "<base href='" + document.URL + "'>";
        winHTML += document.getElementById(id).innerHTML;

    var win = window.open('', '_blank', 'top=10000');
    win.document.open('text/html', '_blank');
    win.document.charset="UTF-8";
    win.document.write('<meta http-equiv="Content-Type" content="' + contentType + '; charset=UTF-8;"><html><head><title>' + title + '</title>' + css + '</head><body>');
    win.document.write(winHTML);
    win.document.write('</body></html>');
    win.document.execCommand('SaveAs', true, title + '.' + contentExt);
    win.close();

}


/**
  * Section: debug options
  */
  
function oDebug(on,to,div){

    this.on  = (on)?on:false;  // 1 = show debug() code | 0 = hide debug() code
    this.to  = (to)?to:"inline"; //alert | status | inline | div (div id="debug"...)
    this.div = (div)?div:"debug"; // The id of the div to output to if the debug to is "div"
    
    this.out = function(s,noBreak,to){
        to = (to)?to:this.to;
        if(s){
            s = (noBreak)?s + "\n":s + "<br>\n";

            if(this.on){
                    if(to=="status"){
                        window.status=s;
                    }else if(to=="alert"){
                        alert(s);
                    }else if(to=="div"){
                        if(document.getElementById(this.div)){
                            document.getElementById(this.div).innerHTML += ("<pre>" + s + "</pre>");
                        }
                    }else{
                        document.write(s);
                    }
            return true;
            }
        return false;
        }
    }
}




/**
  *     JavaScript prototypical functions
  */



Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};

Function.method('inherits', function (parent) {
    var d = 0, p = (this.prototype = new parent());
    this.method('uber', function uber(name) {
        var f, r, t = d, v = parent.prototype;
        if (t) {
            while (t) {
                v = v.constructor.prototype;
                t -= 1;
            }
            f = v[name];
        } else {
            f = p[name];
            if (f == this[name]) {
                f = v[name];
            }
        }
        d += 1;
        r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
        d -= 1;
        return r;
    });
    return this;
});

function hasValue(a) {

    if(isUndefined(a)){
        return false;
    }else if(isNull(a)){
        return false;
    }else if(a.length==0){
        return false;
    }else if(isWhitespace(a)){
        return false;
    }else if(a=="<!---->"){
        return false;
    }else if(a=="undefined"){
        return false;
    }else if(a==""){
        return false;
    }else{
        return true;
    }
}

function isAlien(a) {
   return isObject(a) && typeof a.constructor != 'function';
}

function isArray(a) {
    return isObject(a) && a.constructor == Array;
}

function isBoolean(a) {
    return typeof a == 'boolean';
}

function isEmpty(o) {
    var i, v;
    if (isObject(o)) {
        for (i in o) {
            v = o[i];
            if (isUndefined(v) && isFunction(v)) {
                return false;
            }
        }
    }
    return true;
}

function isFunction(a) {
    return typeof a == 'function';
}

function isNull(a) {
    return typeof a == 'object' && !a;
}
function isNumber(a) {
    return typeof a == 'number' && isFinite(a);
}

function isObject(a) {
    return (a && typeof a == 'object') || isFunction(a);
}

function isString(a) {
    return typeof a == 'string';
}

function isUndefined(a) {
    return typeof a == 'undefined';
}

function isWhitespace(a){
    //var a = (isObject(a))?eval(a):a;
    var whitespace = " \x0B\x09\x0D\x0A\x0C";

    if((a==null)||(a.length==0))
        return true;

	for(var i=0;i<a.length;i++)
	{
	 var c=a.charAt(i);
	 if(whitespace.indexOf(c)==-1)
	 		return false;
	}
	return true;
}

String.method('entityify', function () {
    return this.replace(/&/g, "&amp;").replace(/</g,
        "&lt;").replace(/>/g, "&gt;");
});

String.method('supplant', function (o) {
    var i, j, s = this, v;
    for (;;) {
        i = s.lastIndexOf('{');
        if (i < 0) {
            break;
        }
        j = s.indexOf('}', i);
        if (i + 1 >= j) {
            break;
        }
        v = o[s.substring(i + 1, j)];
        if (!isString(v) && !isNumber(v)) {
            break;
        }
        s = s.substring(0, i) + v + s.substring(j + 1);
    }
    return s;
});

String.method('trim', function () {
    return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
});

if (!isFunction(Function.apply)) {
    Function.method('apply', function (o, a) {
        var r, x = '____apply';
        if (!isObject(o)) {
            o = {};
        }
        o[x] = this;
        switch ((a && a.length) || 0) {
        case 0:
            r = o[x]();
            break;
        case 1:
            r = o[x](a[0]);
            break;
        case 2:
            r = o[x](a[0], a[1]);
            break;
        case 3:
            r = o[x](a[0], a[1], a[2]);
            break;
        case 4:
            r = o[x](a[0], a[1], a[2], a[3]);
            break;
        case 5:
            r = o[x](a[0], a[1], a[2], a[3], a[4]);
            break;
        case 6:
            r = o[x](a[0], a[1], a[2], a[3], a[4], a[5]);
            break;
        default:
            alert('Too many arguments to apply.');
        }
        delete o[x];
        return r;
    });
}

if (!isFunction(Array.prototype.pop)) {
    Array.method('pop', function () {
        return this.splice(this.length - 1, 1)[0];
    });
}

if (!isFunction(Array.prototype.push)) {
    Array.method('push', function () {
        this.splice.apply(this,
            [this.length, 0].concat(Array.prototype.slice.apply(arguments)));
        return this.length;
    });
}

if (!isFunction(Array.prototype.shift)) {
    Array.method('shift', function () {
        return this.splice(0, 1)[0];
    });
}

if (!isFunction(Array.prototype.splice)) {
    Array.method('splice', function (s, d) {
        var max = Math.max,
            min = Math.min,
            a = [], // The return value array
            e,  // element
            i = max(arguments.length - 2, 0),   // insert count
            k = 0,
            l = this.length,
            n,  // new length
            v,  // delta
            x;  // shift count

        s = s || 0;
        if (s < 0) {
            s += l;
        }
        s = max(min(s, l), 0);  // start point
        d = max(min(isNumber(d) ? d : l, l - s), 0);    // delete count
        v = i - d;
        n = l + v;
        while (k < d) {
            e = this[s + k];
            if (!isUndefined(e)) {
                a[k] = e;
            }
            k += 1;
        }
        x = l - s - d;
        if (v < 0) {
            k = s + i;
            while (x) {
                this[k] = this[k - v];
                k += 1;
                x -= 1;
            }
            this.length = n;
        } else if (v > 0) {
            k = 1;
            while (x) {
                this[n - k] = this[l - k];
                k += 1;
                x -= 1;
            }
        }
        for (k = 0; k < i; ++k) {
            this[s + k] = arguments[k + 2];
        }
        return a;
    });
}

if (!isFunction(Array.prototype.unshift)) {
    Array.method('unshift', function () {
        this.splice.apply(this,
            [0, 0].concat(Array.prototype.slice.apply(arguments)));
        return this.length;
    });
}

function wait(sec){
d = new Date() //today's date
while (1)
{
    mill=new Date() // Date Now
    diff = mill-d //difference in milliseconds
    if( diff > sec ) {break;}
}
}


function dateDiff(start,end,interval,rounding){

    var iOut = 0;

    // Create 2 error messages, 1 for each argument.
    var startMsg = "Check the Start Date and End Date\n"
        startMsg += "must be a valid date format.\n\n"
        startMsg += "Please try again." ;

    var intervalMsg = "Sorry the dateAdd function only accepts\n"
        intervalMsg += "d, h, m OR s intervals.\n\n"
        intervalMsg += "Please try again." ;

    var bufferA = Date.parse( start ) ;
    var bufferB = Date.parse( end ) ;

    // check that the start parameter is a valid Date.
    if ( isNaN (bufferA) || isNaN (bufferB) ) {
        return startMsg;
    }

    // check that an interval parameter was not numeric.
    if ( interval.charAt == 'undefined' ) {
        // the user specified an incorrect interval, handle the error.
        return intervalMsg;
    }

    var number = bufferB-bufferA ;

    // what kind of add to do?
    switch (interval.charAt(0))
    {
        case 'd': case 'D':
            iOut = parseInt(number / 86400000) ;
            if(rounding) iOut += parseInt((number % 86400000)/43200001) ;
            break ;
        case 'h': case 'H':
            iOut = parseInt(number / 3600000 ) ;
            if(rounding) iOut += parseInt((number % 3600000)/1800001) ;
            break ;
        case 'm': case 'M':
            iOut = parseInt(number / 60000 ) ;
            if(rounding) iOut += parseInt((number % 60000)/30001) ;
            break ;
        case 's': case 'S':
            iOut = parseInt(number / 1000 ) ;
            if(rounding) iOut += parseInt((number % 1000)/501) ;
            break ;
        default:
        // If we get to here then the interval parameter
        // didn't meet the d,h,m,s criteria.  Handle
        // the error.
        return intervalMsg;
    }

    return iOut ;
}
