
//----------------------------------------------------------
// - StringHelper.js - StringBuilder Class, String.format, String.trim
//----------------------------------------------------------
function StringBuilder(value){this.strings = new Array("");this.append(value);}
StringBuilder.prototype.append = function (value){if (value){this.strings[this.strings.length] = value;}}
StringBuilder.prototype.format = function (value){if (value){for(var i = 1; i < arguments.length; i++)
	value = value.replace('{' + (i - 1) + '}', arguments[i]);this.strings[this.strings.length] = value;}}
StringBuilder.prototype.clear = function (){this.strings.length = 1;}
StringBuilder.prototype.toString = function (){return this.strings.join("");}
String.prototype.format = function(){var str = this;for(var i=0;i<arguments.length;i++){
	var re = new RegExp("\\{" + (i) + "\\}","g"); str = str.replace(re, arguments[i]);}return str;}
String.prototype.trim = function(){return this.replace(/^\s+|\s+$/, '');};
//----------------------------------------------------------
//- Debug wrapper for firebug console
//----------------------------------------------------------
 var isFireFox = (navigator.userAgent.indexOf('Firefox')  >= 0) ? true : false;
debug = function(msg) {	if (!window.location.href.match('http://localhost') || !isFireFox) return false; else console.log(msg);}
//----------------------------------------------------------

/*
function init() {
    if (arguments.callee.done) return;
    arguments.callee.done = true;
    if (_timer) clearInterval(_timer);
    // do stuff
};
if (document.addEventListener) document.addEventListener("DOMContentLoaded", init, false);
if (/WebKit/i.test(navigator.userAgent)) {var _timer = setInterval(function() {if (/loaded|complete/.test(document.readyState)) init();}, 10); };
window.onload = init; //other browsers
*/
      
//----------------------------------------------------------
//- Google MAP Latebinding
//----------------------------------------------------------
var DGMapLoader = function() {
    var _loaded = false;
    this.loaded=_isLoaded;
    this.load=_load;
    this.callback=_callback;
    this.onLoad;
    
    function _isLoaded() { return _loaded; };

    function _GMap_getAPIkey() {
        if (window.location.href.match('http://localhost'))                         return "ABQIAAAAuIWSkGrGNZqgHHypd712uxTIOzwwlQlj6_E1PijJRTb2tVBLcRQoCuNQJteJb9qqDJC7jBKNQ14mNw";
        if (window.location.href.match('http://www2.dupont.com'))                   return "ABQIAAAAuIWSkGrGNZqgHHypd712uxSfEadimc4dhEs-7c-GX8WKOIQDOxQncurPjXY-Zs0aUn_eC7qGoDcAmg";
        if (window.location.href.match('http://ts-internet-stg.lvs.dupont.com'))    return "ABQIAAAABVOjPd-wD-7AntgnuSjIvRSqX-MJG24V3P4dBtq8coOOdSpxQBTG-HZ8eXg9v8LUQWo9cQSKfc7zIQ";
        if (window.location.href.match('http://intw01.lvs.dupont.com'))             return "ABQIAAAABVOjPd-wD-7AntgnuSjIvRT-RWAGnz0nkWMCmg9mVfKeH3-KHRSJamvec-n5uW9oMdnh4Z_XzCMPJg";
    }
     
    function _callback() {
        debug("loading google maps API complete.");
        if (this.onLoad) this.onLoad();
        _loaded = true;
    }
    function _dynaInclude(url) { 
        var e = document.createElement("script");
        e.src = url;e.type="text/javascript";e.id="__DGMAP";
        document.getElementsByTagName("head")[0].appendChild(e);
        }

    function _load(onLoad){
        this.onLoad=onLoad;
        var script = document.getElementById("__DGMAP");  //use this id for early binding to stop being added twice
        if (_loaded == false && script == null) {
            var gMapUri="http://maps.google.com/maps?file=api&v=2.x&async=2&callback=gmapMgr.callback&key="+_GMap_getAPIkey();
            debug("loading google maps API... uri: " + gMapUri);
            _dynaInclude(gMapUri); 
            }
         else {
                if (this.onLoad) this.onLoad();
                _loaded = true;
                }
        }
}
var gmapLoader = new DGMapLoader();
//----------------------------------------------------------
    

//----------------------------------------------------------
function Drpc(args) {
    if (!args.url) throw "url not defined";
    if (!args.onSuccess) throw "onSuccess method not defined";
    if (!args.method) args.method = "GET";
    if (!args.mimeType) args.mimeType = "text/plain";
    if (!(args.mimeType == "text/plain" || args.mimeType == "text/xml")) throw "Unknown mime type: " + args.mimeType;

    var xmlhttp=null;
    if (window.XMLHttpRequest) { 
        xmlhttp=new XMLHttpRequest();                                                       // code for Firefox, Mozilla, IE7, Safari, etc....
        try {
        	//netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        	if (isFireFox) netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");   // firefox cross-domain acess (need to include settings in user pref) 
        	}
        catch(e){}      
        }
    else if (window.ActiveXObject) xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");          // code for IE6, IE5
    if (xmlhttp!=null) xmlhttp.open(args.method,args.url,false);
    else alert("Your browser does not support XMLHTTP."); 
    if (xmlhttp.overrideMimeType) xmlhttp.overrideMimeType(args.mimeType);
    if (args.requestData) xmlhttp.send(args.requestData);
    else xmlhttp.send(null);

    if (xmlhttp.status == 200) args.onSuccess(xmlhttp); 
    else if (args.onFailure) args.onFailure(xmlhttp); 
}
//----------------------------------------------------------
    

//---------------------------------------------
//--	Products class
//---------------------------------------------
    var DproductMgr = function() {
        var TEMPL_PRODUCT_ENDPOINT = "http://www2.dupont.com/NOWApp/DPPRequestGateway?command=ACNOWLocator&search=product&subset={0}";
    	var DEFAULT_PRODUCTMASK = 281474976710655;
    	
    	this.products = null; 
        this.get = _Get;
        this.subset = "BI.Tyvek";
        this.refresh = _refresh;
        this.filter = _filter;
        this.getMask_Select = _getMask_Select;
        this.getMask_Checkbox = _getMask_Checkbox;
        this.populateSelect = _populateSelect; 
        this.populateCheckboxes = _populateCheckboxes; 
              
        function _Get() { 
            if (this.products == null) this.refresh();
            return this.products; 
        }
        
    	function _filter(pmask) {
    		var arr = [];
    		if (this.products == null) this.refresh();
			for (var i=0;i< this.products.length;i++)
				if ((!pmask) || (pmask & this.products[i].mask)>0 )
				 arr[arr.length] = this.products[i];
			return arr;
			}

        function _refresh()
        {
            var parentclass = this;
            Drpc({
			url: TEMPL_PRODUCT_ENDPOINT.format(this.subset),
		    method: "GET",
		    onSuccess : function(resp) {
		    	var p = eval( '(' + resp.responseText.replace("'","&quot;") + ')' );
		    	parentclass.products = p.data;
		    	loadcomplete=true;
		    	return;
		        },
		    onFailure : function(resp) {
		         loadcomplete=true;
		         alert("Failed Loading Products " + resp);
		         return;
		        }
		    });
        }
        
        //gets the mask from the Select Id
    	function _getMask_Select(ename)
    	{
	    	var pm=parseInt(0);
	    	var ops=document.getElementsByName(eid).options;
	   		for (var i=0;i<ops.length;i++)
	   			if (ops[i].selected) pm += parseInt(ops[i].value);
	   		if (pm==0) pm=DEFAULT_PRODUCTMASK;
	   		return pm;
    	}
    
        function _getMask_Checkbox(ename)
    	{
	    	var pm=parseInt(0);
	    	var cbs=document.getElementsByName(ename);
	   		for (var i=0;i<cbs.length;i++)
	   			if (cbs[i].checked) pm += parseInt(cbs[i].value);
	   		//if (pm==0) pm=DEFAULT_PRODUCTMASK;
	   		return pm;
    	}	

        /// args: Id, Name, mask, excludeAll
    	function _populateSelect(args)
    	{
    	if (!args.name && !args.id) throw "Id or name not defined";
    	var mask=281474976710655;  //48bit
    	var sel = null;
    	if (args.id) sel=document.getElementById(args.id);
    	if (args.name)sel=document.getElementsByName(args.name);
    	sel.options.length=0;
    	if (args.mask) mask=args.mask;
    	if (!args.excludeAll) {
    	    var opt = document.createElement('OPTION');
            opt.setAttribute('value',mask);
            opt.appendChild(document.createTextNode("(all)"));
            sel.appendChild(opt);
            }
    	var prods = this.filter(mask);
    	for (var i=0;i<prods.length;i++) {   
    	    var opt = document.createElement('OPTION');
            opt.setAttribute('value',prods[i].mask);
            opt.appendChild(document.createTextNode(prods[i].name));
            sel.appendChild(opt);
            }
    	}
    	
    	        /// args: Id, Name, mask, excludeAll
    	function _populateCheckboxes(args)
    	{
    	if (!args.name && !args.id) throw "Id not defined";
    	var mask=281474976710655;  //48bit
    	var sel = null;
    	if (args.id) div=document.getElementById(args.id);
    	if (args.mask) mask=args.mask;
        sb = new StringBuilder();
        sb.append("<table>");
    	var prods = this.filter(mask);
    	for (var i=0;i<prods.length;i++) {   
    	    sb.format("<tr><td align='right'><input id='Ckbox_{0}' type='checkbox' value='{0}' name='ckProducts'/></td><td align='left'>{1}</td></tr>",prods[i].mask, prods[i].name);
            }
        sb.append("</table>");
        div.innerHTML=sb.toString();
    	}

}
//---------------------------------------------


//---------------------------------------------
//--	Locations class
//---------------------------------------------
    var DlocationMgr = function() {
        var LOCATOR_ENDPOINT = "http://www2.dupont.com/NOWApp/DPPRequestGateway?command=ACNOWLocator&search=location&searchType=radius&originType={0}&origin={1}&subset={2}&productMask={3}&searchCriteria={4}";
    	//var _locs = null;
    	var _origin = null;
    	var _originType = null;
    	this.locations = null;
    	this.mapmgr = null;
    	this.productmask = 281474976710655;
    	this.subset = "BI.Tyvek";
    	this.radius = "25";
    	this.originType = _originType;
    	this.origin = _origin;
    	//this.locs = _locs;
    	this.locate = _locate;                      //gets Origin geocode and locations
    	this.getLocations = _getLocations;
        this.geocodeOrigin = _geocodeOrigin;
        this.filterOR = _filterOR;                  //return the locations using a bitwise OR compare on productmask.
        this.sort = _sort;
          
        function _filterOR(pmask, locs) {
            var out = new Array();
            if (!locs) locs=this.locations;
            if (!pmask) pmask=this.productmask;
            if (!pmask) throw "locations_ORlocs: productmask undefined.";
            for (var i=0; i<locs.length;i++)
               if ((locs[i].productMask & pmask) == pmask)
                    out[out.length] = locs[i];
            return out;
        }
       
        function _sort(args)
            {
            var out;
            try {
                if (args.locations) out=args.locations; else out=this.locations;
                if (!out[0][args.property] && args.sortType!="random") throw "DlocationMgr.sort: Invalid property."
                out.sort( function(a,b) {
                        switch (args.sortType) {
                        
                            case "numeric":
                                return a[args.property] - b[args.property];
                            case "random":
                                return 0.5 - Math.random()
                            default:
                                var x = a[args.property].toLowerCase();
                                var y = b[args.property].toLowerCase();
                                return ((x < y) ? -1 : ((x > y) ? 1 : 0));  
                            }    
                    });
                    if (args.descending) out.reverse();
                }
            catch(e){}
                return out;
            }     
       
       
       
        function _setglobalvars(args, parentclass)  {
            if (args.subset) parentclass.subset = args.subset;
            if (args.productmask) parentclass.productmask = args.productmask;
            if (args.radius) parentclass.radius = args.radius;
            if (args.mapmgr) parentclass.mapmgr = args.mapmgr;
        }
        
        function _locate(args) {
            if (!args.address) throw "locations.locate(): address not defined";
            args.address=args.address.trim();
            if (!args.onSuccess) throw "locations.locate(): onSuccess not defined";
            _setglobalvars(args, this)
            //for optimization this determines if this is a US zip by seeing if it is 5 chars and numberic
            this.originType=null;
            if (args.originType) this.originType = args.originType;
            if (!this.originType)
                if (args.address.length==5 && !isNaN(args.address)) this.originType="zip"; else this.originType="geo";
            switch (this.originType){
                case "geo":
                    //use google's geocoder to determine origin
                    this.geocodeOrigin({
                         address: args.address
                        ,onSuccess: function(point, parentclass) {  
                                        debug("Perform geo search. Point: " + point.toString());
                                        parentclass.getLocations({});
                                        args.onSuccess();
                                        }
                        ,onFailure: function(msg) { 
                                        if (args.onFailure) args.onFailure(msg); 
                                        }
                        });
                    break;
                 case "zip":
                    this.origin = args.address;
                    debug("Perform zip search. zip: " + args.address);
                    this.getLocations({});
                    args.onSuccess();
                    break;
                 default:
                    debug("Invalid originType: " + this.originType);
                    break;
                  }
            }
            
            
        function _getLocations(args) {
            var parentclass = this;
            var strOrigin = null;
            if (args.origin) this.origin = args.origin;
            if (!this.origin) throw "locations.getLocations(): origin not defined";
            _setglobalvars(args, this)
            if (args.originType) this.originType = args.originType;
            if (!this.originType) this.originType = "geo";
            if (this.originType=="geo") strOrigin=this.origin.lng()+","+this.origin.lat(); else strOrigin=this.origin.toUpperCase();
            var uri = LOCATOR_ENDPOINT.format(this.originType,strOrigin,this.subset,this.productmask,this.radius );
            debug("locationURI: " + uri); 
    	    Drpc({
			    url: uri,
			    method: "GET",
	            onSuccess : function(response) {
	                parentclass.locations = null;
	                debug("response: " + response.responseText);
                    var locs = eval( '(' + response.responseText.replace("'","&quot;") + ')' );
                    parentclass.locations = locs.data;
                    debug("Total count: "+parentclass.locations.length);
	    	        if (parentclass.mapmgr) parentclass.mapmgr.plot(parentclass);
	                },
	            onFailure : function(response) {
	                 throw "Unable to get locations. \n" + response;
		            }
		        });
            }
            
        function _getClosestLoc(rank) {
	        var closest;
	        var delta=9999999999999;
	        var j=0;
	        for (j=0;j<locs.data.length;j++)
		        if ( (!rank || rank==locs.data[j].rank) && delta>locs.data[j].distance )
			        {
			        closest=locs.data[j];
			        delta=locs.data[j].distance;
			        }
	        if (!closest && rank>0) closest=getClosestLoc(rank-1)
	        return closest;
	        }
	        
	        
        function _geocodeOrigin(args) {
            var parentclass=this;
            if (!args.address) throw "address is undefined";
            args.address=args.address.trim();
            if (!args.onSuccess) throw "onSuccess is undefined";
            gmapLoader.load( function() {
                    var geocoder = new GClientGeocoder();
                    if (geocoder) { //throw "cannot instantiate Google MAP API call GClientGeocoder()";
                        debug("geocoder.getLatLng("+args.address+")");
                        geocoder.getLatLng(
                            args.address,
                            function(point) {
                                //debug("_getOrigin.getLatLng.Subset: " + this.subset); //scope = window
			                    if (!point) {
			                        var msg = "Error:  Cannot Find Address: " + args.address;
			                        if (args.onFailure) args.onFailure(msg);
			                        else throw msg;
			                        }
			                    else {
			                        parentclass.origin = point;
			                        args.onSuccess(point, parentclass);
			                        }    
                                });
                            }
                    }); //end onLoad
            }
 };//end class
//---------------------------------------------

  