﻿if ( typeof(onccLib) == 'undefined' ) onccLib = function() {};

// ================================================================
// onccLib.strTruncate
onccLib.strTruncate = function (aString, aLength) {
	var tmpVal = new String(onccLib.strRemoveBR(aString));
	var oriVal = new String(tmpVal);
	var retVal = '';
	var i = 0;
	var j = 0;
	while ((i<tmpVal.length)&&(j<aLength)) {
		if (j<aLength) {
			if ((tmpVal.charAt(i)=='&')&&(i+1<tmpVal.length)) {
				if (tmpVal.charAt(i+1)=='#') {
					var stop = false;
					var ccode = '';
					ccode += tmpVal.charAt(i++); // &
					ccode += tmpVal.charAt(i++); // #
					while ((i<tmpVal.length)&&(!stop)) {
						if (tmpVal.charAt(i)==';') {
							stop=true;
							retVal += ccode+';';
							i++;j++;
						} else if ((tmpVal.charCodeAt(i)>=48)&&(tmpVal.charCodeAt(i)<=57)) {
							ccode += tmpVal.charAt(i++);
						} else {
							stop=true;
							if (retVal.length+2<aLength) {
								retVal += ccode+tmpVal.charAt(i++);
								j += 2;
							} else {
								retVal += ccode;
								j++;
							}
						}
					}
				} else {
					retVal += tmpVal.charAt(i++);
					j++;
				}
			} else {
				retVal += tmpVal.charAt(i++);
				j++;
			}
		}
	}
	retVal+=(j==aLength)&&(i<oriVal.length)?'...':'';
	return retVal;
};
onccLib.strRemoveBR = function (aString) {
	var retVal = String(aString);
	var brRegExp = /&lt;br&gt;/gi;
	return retVal.replace(brRegExp, '');
};
// Class Method: dateFormat(dateString, formatString)
onccLib.dateFormat = function (aDateStr, aFormatStr) {
	// Some common format strings
	var masks = {
		'default':      'ddd mmm dd yyyy HH:MM:ss',
		shortDate:      'm/d/yy',
		mediumDate:     'mmm d, yyyy',
		longDate:       'mmmm d, yyyy',
		fullDate:       'dddd, mmmm d, yyyy',
		shortTime:      'h:MM TT',
		mediumTime:     'h:MM:ss TT',
		longTime:       'h:MM:ss TT Z',
		isoDate:        'yyyy-mm-dd',
		isoTime:        'HH:MM:ss',
		isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
		isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
	};

	// Internationalization strings
	var i18n = {
		dayNames: [
			'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat',
			'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
		],
		monthNames: [
			'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
			'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'
		]
	};

	var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
		timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
		timezoneClip = /[^-+\dA-Z]/g,
		pad = function (val, len) {
			val = String(val);
			len = len || 2;
			while (val.length < len) val = '0' + val;
			return val;
		};

	var formatter = function (date, mask, utc) {

			// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
			if (arguments.length == 1 && (typeof date == 'string' || date instanceof String) && !/\d/.test(date)) {
				mask = date;
				date = undefined;
			}

			// Passing date through Date applies Date.parse, if necessary
			date = date ? new Date(date) : new Date();
			if (isNaN(date)) throw new SyntaxError('invalid date');

			mask = String(masks[mask] || mask || masks['default']);

			// Allow setting the utc argument via the mask
			if (mask.slice(0, 4) == 'UTC:') {
				mask = mask.slice(4);
				utc = true;
			}

			var	_ = utc ? 'getUTC' : 'get',
				d = date[_ + 'Date'](),
				D = date[_ + 'Day'](),
				m = date[_ + 'Month'](),
				y = date[_ + 'FullYear'](),
				H = date[_ + 'Hours'](),
				M = date[_ + 'Minutes'](),
				s = date[_ + 'Seconds'](),
				L = date[_ + 'Milliseconds'](),
				o = utc ? 0 : date.getTimezoneOffset(),
				flags = {
					d:    d,
					dd:   pad(d),
					ddd:  i18n.dayNames[D],
					dddd: i18n.dayNames[D + 7],
					m:    m + 1,
					mm:   pad(m + 1),
					mmm:  i18n.monthNames[m],
					mmmm: i18n.monthNames[m + 12],
					yy:   String(y).slice(2),
					yyyy: y,
					//h:    H % 12 || 12 remove by James 18/11
					h:    H,
					hh:   pad(H),
					H:    H,
					HH:   pad(H),
					M:    M,
					MM:   pad(M),
					s:    s,
					ss:   pad(s),
					l:    pad(L, 3),
					L:    pad(L > 99 ? Math.round(L / 10) : L),
					t:    H < 12 ? 'a'  : 'p',
					tt:   H < 12 ? 'am' : 'pm',
					T:    H < 12 ? 'A'  : 'P',
					TT:   H < 12 ? 'AM' : 'PM',
					Z:    utc ? 'UTC' : (String(date).match(timezone) || ['']).pop().replace(timezoneClip, ''),
					o:    (o > 0 ? '-' : '+') + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
					S:    ['th', 'st', 'nd', 'rd'][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
				};

			return mask.replace(token, function ($0) {
				return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
			});
		};

	var yyyy = aDateStr.substring(0,4);
	var mm = parseInt(aDateStr.substring(4,6), 10) - 1;
	var dd = aDateStr.substring(6,8);
	var HH = aDateStr.substring(8,10);
	var MM = aDateStr.substring(10,12);
	var ss = aDateStr.substring(12,14);
	var theDate = new Date(yyyy, mm, dd, HH, MM, ss);
	
	return formatter(theDate, aFormatStr, false);
};

// ================================================================
// onccLib.Events
onccLib.Events = function (element) {
	this.element = element;
};
// Method: addListener(element, type, expression, bubbling)
// Cross-browser implementation of element.addEventListener()
// Useage: addListener(window, 'load', myFunction);
onccLib.Events.prototype.addListener = function(type, expression, bubbling) {
	bubbling = bubbling || false;
	if (window.addEventListener) { // Standard
		this.element.addEventListener(type, expression, bubbling);
		return true;
	} else if (window.attachEvent) { // IE
		this.element.attachEvent('on' + type, expression);
		return true;
	} else return false;
};
// Class Method: getEventTarget(event)
onccLib.Events.getEventTarget = function (e) {
	var targ;
	if (!e) var e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ.nodeType == 3) // defeat Safari bug
		targ = targ.parentNode;
	return targ;
};

// ================================================================
// onccLib.Cookies object
onccLib.Cookies = function () {
	var allCookies = document.cookie.split('; ');
	for (var i=0;i<allCookies.length;i++) {
		var cookiePair = allCookies[i].split('=');
		this[cookiePair[0]] = cookiePair[1];
	}
};
// Method: create()
onccLib.Cookies.prototype.create = function(pName, pValue, pDays) {
	if (pDays) {
		var date = new Date();
		date.setTime(date.getTime()+(pDays*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = pName+"="+pValue+expires+"; path=/";
	this[pName] = pValue;
};
// Method: erase()
onccLib.Cookies.prototype.erase = function(pName) {
	this.Create(pName,'',-1);
	this[pName] = undefined;
};

// ================================================================
//  class: onccLib.ParseXML 
onccLib.ParseXML = function ( url, query, method ) {
    this.http = new onccLib.ParseXML.HTTP( url, query, method, false );
    return this;
};
//  class variables
onccLib.ParseXML.MIME_TYPE_XML  = 'text/xml';
onccLib.ParseXML.MAP_NODETYPE = [
    '',
    'ELEMENT_NODE', //1
    'ATTRIBUTE_NODE', //2
    'TEXT_NODE', //3
    'CDATA_SECTION_NODE', //4
    'ENTITY_REFERENCE_NODE', //5
    'ENTITY_NODE', //6
    'PROCESSING_INSTRUCTION_NODE', //7
    'COMMENT_NODE', //8
    'DOCUMENT_NODE', //9
    'DOCUMENT_TYPE_NODE', //10
    'DOCUMENT_FRAGMENT_NODE', //11
    'NOTATION_NODE' //12
];
//  define callback function (ajax)
onccLib.ParseXML.prototype.async = function ( func, args ) {
    this.callback_func = func;      // callback function
    this.callback_arg  = args;      // first argument
};
onccLib.ParseXML.prototype.onerror = function ( func, args ) {
    this.onerror_func = func;       // callback function
};
//  method: parse()
//  return: parsed object
//  Download a file from remote server and parse it.
onccLib.ParseXML.prototype.parse = function () {
    if ( ! this.http ) return;
    if ( this.onerror_func ) {
        this.http.onerror( this.onerror_func );
    }
    if ( this.callback_func ) {                             // async mode
        var copy = this;
        var proc = function() {
            if ( ! copy.http ) return;
            var data = copy.parseResponse();
            copy.callback_func( data, copy.callback_arg );  // call back
        };
        this.http.async( proc );
    }
    this.http.load();
    if ( ! this.callback_func ) {                           // sync mode
        var data = this.parseResponse();
        return data;
    }
};
//  every child/children into array
onccLib.ParseXML.prototype.setOutputArrayAll = function () {this.setOutputArray( true );}
//  a child into scalar, children into array
onccLib.ParseXML.prototype.setOutputArrayAuto = function () {this.setOutputArray( null );}
//  every child/children into scalar (first sibiling only)
onccLib.ParseXML.prototype.setOutputArrayNever = function () {this.setOutputArray( false );}
//  specified child/children into array, other child/children into scalar
onccLib.ParseXML.prototype.setOutputArrayElements = function ( list ) {this.setOutputArray( list );}
//  specify how to treate child/children into scalar/array
onccLib.ParseXML.prototype.setOutputArray = function ( mode ) {
    if ( typeof(mode) == 'string' ) {
        mode = [ mode ];                // string into array
    }
    if ( mode && typeof(mode) == 'object' ) {
        if ( mode.length < 0 ) {
            mode = false;               // false when array == [] 
        } else {
            var hash = {};
            for( var i=0; i<mode.length; i++ ) {
                hash[mode[i]] = true;
            }
            mode = hash;                // array into hashed array
            if ( mode['*'] ) {
                mode = true;            // true when includes '*'
            }
        } 
    } 
    this.usearray = mode;
}
//  method: parseResponse()
onccLib.ParseXML.prototype.parseResponse = function () {
    var root = this.http.documentElement();
    var data = this.parseDocument( root );
    return data;
}
//  convert from DOM root node to JavaScript Object 
//  method: parseElement( rootElement )
onccLib.ParseXML.prototype.parseDocument = function ( root ) {
    if ( ! root ) return;
    var ret = this.parseElement( root );            // parse root node
    if ( this.usearray == true ) {                  // always into array
        ret = [ ret ];
    } else if ( this.usearray == false ) {          // always into scalar
        //
    } else if ( this.usearray == null ) {           // automatic
        //
    } else if ( this.usearray[root.nodeName] ) {    // specified tag
        ret = [ ret ];
    }
    var json = {};
    json[root.nodeName] = ret;                      // root nodeName
    return json;
};
//  convert from DOM Element to JavaScript Object 
//  method: parseElement( element )
onccLib.ParseXML.prototype.parseElement = function ( elem ) {
    //  COMMENT_NODE
    if ( elem.nodeType == 7 ) {
        return;
    }

    //  TEXT_NODE CDATA_SECTION_NODE
    if ( elem.nodeType == 3 || elem.nodeType == 4 ) {
        var bool = elem.nodeValue.match( /[^\x00-\x20]/ ); // for Safari
        if ( bool == null ) return;     // ignore white spaces
        return elem.nodeValue;
    }

    var retval;
    var cnt = {};

    //  parse attributes
    if ( elem.attributes && elem.attributes.length ) {
        retval = {};
        for ( var i=0; i<elem.attributes.length; i++ ) {
            var key = elem.attributes[i].nodeName;
           if ( typeof(key) != 'string' ) continue;
            var val = elem.attributes[i].nodeValue;
            if ( ! val ) continue;
            if ( typeof(cnt[key]) == 'undefined' ) cnt[key] = 0;
            cnt[key] ++;
            this.addNode( retval, key, cnt[key], val );
        }
    }

    //  parse child nodes (recursive)
    if ( elem.childNodes && elem.childNodes.length ) {
        var textonly = true;
        if ( retval ) textonly = false;        // some attributes exists
        for ( var i=0; i<elem.childNodes.length && textonly; i++ ) {
            var ntype = elem.childNodes[i].nodeType;
            if ( ntype == 3 || ntype == 4 ) continue;
            textonly = false;
        }
        if ( textonly ) {
            if ( ! retval ) retval = '';
            for ( var i=0; i<elem.childNodes.length; i++ ) {
                retval += elem.childNodes[i].nodeValue;
            }
        } else {
            if ( ! retval ) retval = {};
            for ( var i=0; i<elem.childNodes.length; i++ ) {
                var key = elem.childNodes[i].nodeName;
                if ( typeof(key) != 'string' ) continue;
                var val = this.parseElement( elem.childNodes[i] );
                if ( ! val ) continue;
                if ( typeof(cnt[key]) == 'undefined' ) cnt[key] = 0;
                cnt[key] ++;
                this.addNode( retval, key, cnt[key], val );
            }
        }
    }
    return retval;
};
//  method: addNode( hash, key, count, value )
onccLib.ParseXML.prototype.addNode = function ( hash, key, cnts, val ) {
    if ( this.usearray == true ) {              // into array
        if ( cnts == 1 ) hash[key] = [];
        hash[key][hash[key].length] = val;      // push
    } else if ( this.usearray == false ) {      // into scalar
        if ( cnts == 1 ) hash[key] = val;       // only 1st sibling
    } else if ( this.usearray == null ) {
        if ( cnts == 1 ) {                      // 1st sibling
            hash[key] = val;
        } else if ( cnts == 2 ) {               // 2nd sibling
            hash[key] = [ hash[key], val ];
        } else {                                // 3rd sibling and more
            hash[key][hash[key].length] = val;
        }
    } else if ( this.usearray[key] ) {
        if ( cnts == 1 ) hash[key] = [];
        hash[key][hash[key].length] = val;      // push
    } else {
        if ( cnts == 1 ) hash[key] = val;       // only 1st sibling
    }
};

// ================================================================
//  class: onccLib.ParseXML.HTTP
//  constructer: new onccLib.ParseXML.HTTP()
onccLib.ParseXML.HTTP = function( url, query, method, textmode ) {
    this.url = url;
    if ( typeof(query) == 'string' ) {
        this.query = query;
    } else {
        this.query = '';
    }
    if ( method ) {
        this.method = method;
    } else if ( typeof(query) == 'string' ) {
        this.method = 'POST';
    } else {
        this.method = 'GET';
    }
    this.textmode = textmode ? true : false;
    this.req = null;
    this.xmldom_flag = false;
    this.onerror_func  = null;
    this.callback_func = null;
    this.already_done = null;
    return this;
};
//  class variables
onccLib.ParseXML.HTTP.REQUEST_TYPE  = 'application/x-www-form-urlencoded';
onccLib.ParseXML.HTTP.ACTIVEX_XMLDOM  = 'Microsoft.XMLDOM';  // Msxml2.DOMDocument.5.0
onccLib.ParseXML.HTTP.ACTIVEX_XMLHTTP = 'Microsoft.XMLHTTP'; // Msxml2.XMLHTTP.3.0
onccLib.ParseXML.HTTP.EPOCH_TIMESTAMP = 'Thu, 01 Jun 1970 00:00:00 GMT'
onccLib.ParseXML.HTTP.prototype.onerror = onccLib.ParseXML.prototype.onerror;
onccLib.ParseXML.HTTP.prototype.async = function( func ) {
    this.async_func = func;
}
//  method: load(  )
onccLib.ParseXML.HTTP.prototype.load = function() {
    // create XMLHttpRequest object
    if ( window.ActiveXObject ) {                           // IE5.5,6,7
        var activex = onccLib.ParseXML.HTTP.ACTIVEX_XMLHTTP;    // IXMLHttpRequest
        if ( this.method == 'GET' && ! this.textmode ) {
            // use IXMLDOMElement to accept any mime types
            // because overrideMimeType() is not available on IE6
            activex = onccLib.ParseXML.HTTP.ACTIVEX_XMLDOM;     // IXMLDOMElement
        }
        this.req = new ActiveXObject( activex );
    } else if ( window.XMLHttpRequest ) {                   // Firefox, Opera, iCab
        this.req = new XMLHttpRequest();
    }

    // async mode when call back function is specified
    var async_flag = this.async_func ? true : false;

    // open for XMLHTTPRequest (not for IXMLDOMElement)
    if ( typeof(this.req.send) != 'undefined' ) {
        this.req.open( this.method, this.url, async_flag );
    }

    // Content-Type: application/x-www-form-urlencoded (request header)
    // Some server does not accept without request content-type.
    if ( typeof(this.req.setRequestHeader) != 'undefined' ) {
        this.req.setRequestHeader( 'Content-Type', onccLib.ParseXML.HTTP.REQUEST_TYPE );
    }

    // Content-Type: text/xml (response header)
    // FireFox does not accept other mime types like application/rdf+xml etc.
    if ( typeof(this.req.overrideMimeType) != 'undefined' && ! this.textmode ) {
        this.req.overrideMimeType( onccLib.ParseXML.MIME_TYPE_XML );
    }

    // set call back handler when async mode
    if ( async_flag ) {
        var copy = this;
        copy.already_done = false;                  // not parsed yet
        var check_func = function () {
            if ( copy.req.readyState != 4 ) return;
            var succeed = copy.checkResponse();
            if ( ! succeed ) return;                // failed
            if ( copy.already_done ) return;        // parse only once
            copy.already_done = true;               // already parsed
            copy.async_func();                      // call back async
        };
        this.req.onreadystatechange = check_func;
    }

    // send the request and query string
    if ( typeof(this.req.send) != 'undefined' ) {
        this.req.send( this.query );                        // XMLHTTPRequest
    } else if ( typeof(this.req.load) != 'undefined' ) {
        this.req.async = async_flag;
        this.req.load( this.url );                          // IXMLDOMElement
    }

    // just return when async mode
    if ( async_flag ) return;

    var succeed = this.checkResponse();
}
//  method: checkResponse()
onccLib.ParseXML.HTTP.prototype.checkResponse = function() {
    // parseError on IXMLDOMElement
    if ( this.req.parseError && this.req.parseError.errorCode != 0 ) {
        if ( this.onerror_func ) this.onerror_func( this.req.parseError.reason );
        return false;                       // failed
    }

    // HTTP response code
    if ( this.req.status-0 > 0 &&
         this.req.status != 200 &&          // OK
         this.req.status != 206 &&          // Partial Content
         this.req.status != 304 ) {         // Not Modified
        if ( this.onerror_func ) this.onerror_func( this.req.status );
        return false;                       // failed
    }

    return true;                            // succeed
}
//  method: documentElement()
//  return: XML DOM in response body
onccLib.ParseXML.HTTP.prototype.documentElement = function() {
    if ( ! this.req ) return;
    if ( this.req.responseXML ) {
        return this.req.responseXML.documentElement;    // XMLHTTPRequest
    } else {
       return this.req.documentElement;                // IXMLDOMDocument
    }
}
//  method: responseText()
//  return: text string in response body
onccLib.ParseXML.HTTP.prototype.responseText = function() {
    if ( ! this.req ) return;

    //  Safari and Konqueror cannot understand the encoding of text files.
    if ( navigator.appVersion.match( 'KHTML' ) ) {
        var esc = escape( this.req.responseText );
        if ( ! esc.match('%u') && esc.match('%') ) {
            return decodeURIComponent(esc);
        }
    }

    return this.req.responseText;
}

// ================================================================
//  class: onccLib.ParseXML.Text 
onccLib.ParseXML.Text = function ( url, query, method ) {
    this.http = new onccLib.ParseXML.HTTP( url, query, method, true );
    return this;
};

onccLib.ParseXML.Text.prototype.parse = onccLib.ParseXML.prototype.parse;
onccLib.ParseXML.Text.prototype.async = onccLib.ParseXML.prototype.async;
onccLib.ParseXML.Text.prototype.onerror = onccLib.ParseXML.prototype.onerror;

onccLib.ParseXML.Text.prototype.parseResponse = function () {
    var data = this.http.responseText();
    return data;
}