﻿/*
 Author:  avc
 Date:    10/23/2008
 Input:   string:parent_id, string:character_to_join_with
 Ouput:   string (xxx=123&yyy=456)
 Example: StoreEdit.ascx
 About:
  This will retrieve all inputs inside the specified parent and will
  return a query string style of a string with their name and values.
*/

//original function name but now its an overload
function GetInputs(containerId, joinWith, excludeTypes) {
    return GetFormInputs(containerId, joinWith, excludeTypes, false);
}

//originally "getinputs" but needed an overload to either do encoding or not
function GetFormInputs(containerId, joinWith, excludeTypes, doEncode) {
    var inputs = [];

    $(':input', containerId).each(function() {
        if ($(this).attr('type') != 'submit') {
            var val = this.value;
            var canPush = true;
            
            if(doEncode) {
                val = encodeURIComponent(val);
            } else {
                //always need to escape &'s
                val = val.replace(/&/, "%26");            
            }
            
            if (excludeTypes != null) {
                //this will only add inputs that are not in the excluded type list
                if (excludeTypes.indexOf($(this).attr('type')) != -1) {
                    canPush = false;
                    //inputs.push(this.name + '=' + val); //no longer escape the value                
                }
            }
            
            if(canPush) {
                if($(this).attr('type') == 'checkbox') {
                    inputs.push(this.name + '=' + $(this).attr('checked'));
                } else {
                    inputs.push(this.name + '=' + val); //no longer escape the value
                }            
            }
        }
    })           
    
    if(joinWith == null) { joinWith = '&'; }
    
    var retval = inputs.join(joinWith);
    
    return retval;
};
/*
 Author: avc
 Date:   10/23/2008
 Input:  string:xml
 Ouput:  string
 About:
  This will replace invlaid xml characters with their html
  entities.
*/
function CleanXML(xml) {
    var retval = xml;
    retval = retval.replace("&", "&amp;");
    retval = retval.replace("<", "&lt;");
    retval = retval.replace(">", "&gt;");
    retval = retval.replace("\"", "&quot;");
    retval = retval.replace("\'", "&apos;");    
    
    return retval;
};

/*
 Author: avc
 Date:   10/23/2008
 Input:  string:text
 Ouput:  n/a
 About:
  This will print to the console window for FireFox.
*/
function debug(str) {
if (window.console && window.console.log)
  window.console.log('Debug: '+str);
};
/*
 Author: ?
 Date:   10/23/2008
 Input:  string:number
 Ouput:  string
 About:
  This will format the string object to include $.
*/
function formatCurrency(num){
    num=num.toString().replace(/\$|\,/g,'');
    if(isNaN(num))num="0";
    sign=(num==(num=Math.abs(num)));
    num=Math.floor(num*100+0.50000000001);
    cents=num%100;
    num=Math.floor(num/100).toString();
    if(cents<10)cents="0"+cents;
    for(var i=0;i<Math.floor((num.length-(1+i))/3);i++)
        num=num.substring(0,num.length-(4*i+3))+','+num.substring(num.length-(4*i+3));
    return(((sign)?'':'-')+'$'+num+'.'+cents)
}

/*
 Author:  avc
 Date:    10/23/2008
 Input:   object:input
 Ouput:   n/a
 Example: StoreCreate.ascx
 About:
  This will validate the input object.  If found invalid it
  will mark it up as so.
*/
function Validate(obj){
    var inputDiv = $(obj).parent('div');
    var validationtype = $(obj).attr('validationtype');
    var val = $.trim($(obj).attr('value'));
    var valLength = val.length;
    var minChar = $.trim($(obj).attr('minCharacters'));
    var maxChar = $.trim($(obj).attr('maxCharacters'));
    var hasDefault = $(obj).hasClass('defaultText');
    var defaultText = $(obj).attr('title');
    var valid = true;
    var msg = '';
    //debug(validationtype);
    if($(inputDiv).attr('class') == 'required'){
        if(val == '' || hasDefault && val == defaultText){
            valid = false;
            msg = 'required field';
        }
    }
    switch(validationtype){
        case 'number':
            if(isNaN(val)){
                valid = false;
                msg = 'numbers only';
            }
        break;
        case 'email':
            if(!ValidateEmail(val)){
                valid = false;
                msg = 'invalid email address format';
            }
        break;        
        case 'zipcode':
            if(!ValidateZipCode(val)){
                valid = false;
                msg = 'invalid zip code format';
            }
        break;                
        case 'phonenumber':
            if(!ValidatePhoneNumber(val)){
                valid = false;
                msg = 'invalid phone number format';
            }
        break;                
    }    
    
    //check the minCharacters attr on input field
    if(valid && minChar && valLength < minChar){
        valid = false;
        msg = 'minimum characters: '+minChar;
    }
    
    //check the maxCharacters attr on input field
    if(valid && maxChar && valLength > maxChar){
        valid = false;
        msg = 'maximum characters: '+maxChar;
    }
    
    if(valid){
        MarkInputValid(obj);
    }
    else{
        MarkInputInvalid(obj, msg);
    }
    
    return valid;
}
/*
 Author: avc
 Date:   10/23/2008
 Input:  object:input
 Ouput:  n/a
 About:
  This will remove the invalid style on the input object.
*/
function MarkInputInvalid(obj, msg){
    var inputDiv = $(obj).parent('div');
    $('span.errorMessage', $(inputDiv)).remove();
    $('label:first', $(inputDiv)).addClass('invalid');
    //avc >> the .focus() event will crash IE... 
    $(obj).css({'border':'2px solid #ab4a4a',color:'#000'}).after('<span class="errorMessage"><i>&nbsp;('+msg+')</i></span>');//.focus()
    //$('input:submit').attr({disabled:true}).animate({opacity:.4});
}
/*
 Author: avc
 Date:   10/23/2008
 Input:  object:input
 Ouput:  n/a
 About:
  This will add style to the input object to show that it
  contains invalid data.
*/
function MarkInputValid(obj){
    var inputDiv = $(obj).parent('div');
    $('label:first', $(inputDiv)).removeClass('invalid');
    $('span.errorMessage', $(inputDiv)).remove();
    $(obj).css({'border':'1px solid #D0D0D0',color:''});    
    //$('input:submit').attr({disabled:false}).animate({opacity:1});
}
/*
 Author: avc
 Date:   10/23/2008
 Input:  string:parent_id
 Ouput:  n/a
 About: 
  ResetValidation will do just that, pass it the containing element id and
  it will reset all invalid validation items.
*/
function ResetValidation(parent){
    $(':input', parent).each(function() {
        var inputDiv = $(this).parent('div');
        $('label:first', $(inputDiv)).removeClass('invalid');
        $('span.errorMessage', $(inputDiv)).remove();
        $(this).css({'border':'1px solid #D0D0D0',color:''});            
    });
}
/*
 Author: avc
 Date:   10/23/2008
 Input:  string:email
 Ouput:  bool
 About: 
  Pass in the string email address and this will use RegEx to validate the
  format of the email.
*/
function ValidateEmail(email){
    //pattern came from: http://xyfer.blogspot.com/2005/01/javascript-regexp-email-validator.html
    var emailPattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
    return emailPattern.test(email)
}
/*
 Author: avc
 Date:   10/23/2008
 Input:  string:zipcode
 Ouput:  bool
 About: 
  Pass in the string zip code and this will use RegEx to validate the
  format of the email.
*/
function ValidateZipCode(zip){
    var zipPattern = new RegExp(/^\d{5}$|^\d{5}-\d{4}$/i);
    return zipPattern.test(zip);
}
/*
 Author: avc
 Date:   10/23/2008
 Input:  string:phoneNumber
 Ouput:  bool
 About: 
  Pass in the string phone number and this will use RegEx to validate the
  format of the phone number.
*/
function ValidatePhoneNumber(number){
    var phoneNumberPattern = new RegExp(/^\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})$/i);
    return phoneNumberPattern.test(number)
}
/*
 Author: avc
 Date:   1/13/2009
 Input:  string:cookie (name=albert;age=28;weight=175;)
 Input:  string:name (age)
 Input:  string:value optional (55)
 Ouput:  string value
 About: 
    Used for cookie manipulation. Pass in the full cookie value, and if you want just a value
    of one of the items then just pass in the name, or if you want to set a value of an item
    then you pass in the value also.
 Example: var ret = CookieCutter(tmpstring, 'AGE', '50'); [will set the age to 50 and return the full string]
 Example: var ret = CookieCutter(tmpstring, 'AGE', null); [will grab the age value]
*/
function CookieCutter(cookie, name, splitBy, newValue) {
    var retval = '';
    cookie = cookie.toLowerCase();
    name = name.toLowerCase();
    
    if(splitBy == null) {
        splitBy = ';';
    }
    
    if(newValue == null) {
        //just grab value
        var tmp = cookie.split(splitBy);
        for(i = 0; i < tmp.length; i++) {
            var tmpPair = tmp[i].split("=");
            var nme = tmpPair[0];
            var val = tmpPair[1];
            
            if(name.toLowerCase() == nme.toLowerCase()) {
                retval = val;
            }
        }
    }
    else {
        //set value
        retval = cookie;
        //newValue = newValue.toLowerCase();
        var tmp = cookie.split(splitBy);
        for(i = 0; i < tmp.length; i++) {
            var tmpPair = tmp[i].split("=");
            var nme = tmpPair[0];
            var val = tmpPair[1];
            
            if(name == nme) {
                //set new value
                retval = retval.replace(nme + "=" + val + splitBy, nme + "=" + newValue + splitBy);
            }
        }        
    }
    
    return retval;
}

/*
 Author: avc
 Date:   6/26/2009
 Input:  string:cookie (name=albert&age=28&weight=175&split=default.aspx=270|department.aspx=199)
 Input:  string:name (default.aspx)
 Input:  string:value optional (154)
 Ouput:  string value, will depend on what you call it with
 About: 
    Used for the split data of a cookie. Pass in the full cookie value, and if you want just a value
    of one of the items then just pass in the name, or if you want to set a value of an item
    then you pass in the value also.
 Example: var ret = SplitCookieCutter(fullCookieString, 'default.aspx', '150'); [will set the default.aspx page to styleid 150
          and will return the full string]
 Example: var ret = SplitCookieCutter(fullCookieString, 'default.aspx', null); [will just grab the 
          default.aspx styleid]
*/
function SplitCookieCutter(cookie, name, newValue) {
    var retval = '';
    cookie = cookie.toLowerCase();
    var tmp = cookie.split("&");
    
    if(name != null) {
        name = name.toLowerCase();
    }
    
    if(newValue == null && name == null) {
        //pull all keys    
        for(i = 0; i < tmp.length; i++) {
            if(tmp[i].toLowerCase().indexOf("split=") != -1) {
                //returns: default.aspx=177|Product.aspx=203
                retval = tmp[i].substring(6);
            }
        }
    } else if (name != null && newValue == null) {
        //just pull one key
        for(i = 0; i < tmp.length; i++) {
            if(tmp[i].toLowerCase().indexOf("split=") != -1) {
                //returns: default.aspx=177
                var tmpSplits = tmp[i].substring(6);
                var tmpSplitPages = tmpSplits.split("|");
                
                for(j = 0; j < tmpSplitPages.length; j++) {
                    var tmpSplitPage = tmpSplitPages[j].split("=");
                    var key = tmpSplitPage[0].toLowerCase();
                    var value = tmpSplitPage[1].toLowerCase();
                    if(key == name) {
                        retval = key + "=" + value;        
                    }
                }
            }        
        }
    } else {
        //set value
        retval = cookie;
        for(i = 0; i < tmp.length; i++) {
            if(tmp[i].toLowerCase().indexOf("split=") != -1) {
                //returns: entire cookie string with new values
                var tmpSplits = tmp[i].substring(6);
                var tmpSplitPages = tmpSplits.split("|");
                
                for(j = 0; j < tmpSplitPages.length; j++) {
                    var tmpSplitPage = tmpSplitPages[j].split("=");
                    var key = tmpSplitPage[0].toLowerCase();
                    var value = tmpSplitPage[1].toLowerCase();
                    if(key == name) {
                        retval = retval.replace(key + "=" + value , key + "=" + newValue);        
                    }
                }
            }        
        }        
    }
    
    return retval;
}
/*
 * Date Format 1.2.2
 * (c) 2007-2008 Steven Levithan <stevenlevithan.com>
 * MIT license
 * Includes enhancements by Scott Trenda <scott.trenda.net> and Kris Kowal <cixar.com/~kris.kowal/>
 *
 * Accepts a date, a mask, or a date and a mask.
 * Returns a formatted version of the given date.
 * The date defaults to the current date/time.
 * The mask defaults to dateFormat.masks.default.
 */
var dateFormat = function () {
	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;
		};

	// Regexes and supporting functions are cached through closure
	return function (date, mask, utc) {
		var dF = dateFormat;

		// 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(dF.masks[mask] || mask || dF.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:  dF.i18n.dayNames[D],
				dddd: dF.i18n.dayNames[D + 7],
				m:    m + 1,
				mm:   pad(m + 1),
				mmm:  dF.i18n.monthNames[m],
				mmmm: dF.i18n.monthNames[m + 12],
				yy:   String(y).slice(2),
				yyyy: y,
				h:    H % 12 || 12,
				hh:   pad(H % 12 || 12),
				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);
		});
	};
}();

// Some common format strings
dateFormat.masks = {
	"default":      "ddd mmm dd yyyy HH:MM:ss",
	shortDate:      "m/d/yy",
	standardDate:   "mm/dd/yyyy",
	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
dateFormat.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"
	]
};

// For convenience...
Date.prototype.format = function (mask, utc) {
	return dateFormat(this, mask, utc);
};
//end of date format function

/*
 Author: avc
 Date:   3/9/2009
 Input:  string:path to file
 Ouput:  n/a
 About: 
  Adds a link to a js file...
*/
function IncludeJavaScript(jsFile)
{    
    document.write( '<scr' + 'ipt type="text/javascript" src="' + jsFile + '"><\/scr' + 'ipt>' ) ;
}

/*
 Author: avc
 Date:   3/9/2009
 Input:  string:path to file
 Ouput:  n/a
 About: 
  Adds a link to a css file...
*/
function IncludeCSS(cssFile)
{
  document.write('<link type="text/css" rel="stylesheet" href="' + cssFile + '"></link>'); 
}

/*
 Author: avc
 Date:   3/9/2009
 Input:  string:5.3453453, int:2
 Ouput:  '5.34'
 About: 
  returns a number only going x decimal places...
*/
function ParseDecimal(input, decimalPlaces)
{
    if (input == '' || input == null) {
        return '0';
    }
    
    var Whole = input.substr(0, input.indexOf("."));
    var Decimal = input.substr(input.indexOf(".")+1, decimalPlaces);                        
    
    return Whole + '.' + Decimal;  
}

/*
 Author: avc
 Date:   4/15/2009
 Input:  yes or no
 Ouput:  an yes/no option tag to be used in a yes/no select
 About: 
  hmmm
*/
function YesNoOption(val) {
    var retval;
    
    if (val.toLowerCase() == 'yes') {
        retval = '<option value="1" selected="selected">Yes</option><option value="0">No</option>';
    } else {
        retval = '<option value="1">Yes</option><option value="0" selected="selected">No</option>';
    }
    
    return retval;
}

/*
 Author: avc
 Date:   4/15/2009
 Input:  int
 Ouput:  Yes or No
 About: 
  Will return a string value from int
*/
function YesNoFromBit(val) {
    var retval = 'Yes';
    
    if(val < 1) {
        retval = 'No';
    }
    
    return retval;
}

/*
 Author: avc
 Date:   4/15/2009
 Input:  yes or no
 Ouput:  1 or 0
 About: 
  Returns string value for 1 or 0
*/
function BitFromYesNo(val) {
    var retval = 1;
    
    if(val.toLowerCase() == 'no') {
        retval = 0;
    }
    
    return retval;
}

/*
 Author: avc
 Date:   5/12/2009
 Input:  sku
 Ouput:  xml for product if a match is found
 About: 
  Allows you to verify a sku.
*/
function ValidateSKU(sku, callback){
    $.ajax({
       type: "GET",
       dataType: "xml",
       url: "WebServices/ProductDetails.asmx/ViewProductDetailBySKU",
       data: 'sku='+sku,
       error: function(xml){
        debug('failed');
       },       
       success: function(xml){
        //call the callback function
        callback(xml);
       }
    });
}

/*
 Author:  avc
 Date:    06/04/2009
 Input:   string:container id, string:excluded types
 Ouput:   n/a
 Example: Split.ascx
 About:
  This will reset all inputs.
*/
function ResetForm(containerId, excludeTypes) {
    var canReset = false;
    
    $(':input', containerId).each(function() {
        if ($(this).attr('type') != 'submit') {
            if (excludeTypes == null) {
                canReset = true;
            } else {
                //this will only clear the inputs that are not in the excluded type list
                if (excludeTypes.indexOf($(this).attr('type')) == -1) {
                    canReset = true;
                }
            }
            
            if(canReset) {
                if($(this).attr('type') == 'select') {
                    this.val = '0';
                } else {
                    this.val = '';
                }
            }
        }
    })           
};

/*
 Author:  avc
 Date:    07/20/2009
 Input:   string:id
 Ouput:   n/a
 Example: StyleEdit.ascx
 About:   will copy the html of the id that you pass it to the clipboard.
 Note:    firefox only...and you will need to:
            In the firefox address bar, type in: "about:config"
            (no quotes), and hit enter.
            In the "filter" box you now see, type in the word
            "signed", and you should only have one result coming
            up. It's set to DISABLED. Double-click it, and it
            should change to ENABLED. Close the window. From then
            on, firefox will warn you when a website tries to
            access your clipboard, and you can tell it to "always
            allow this site...."
*/
function FireFoxCopyToClipboard(id) {
    var text2copy = $(id).val();

    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');

    var Cc = Components.classes;
    var Ci = Components.interfaces;
    var Cstr = Cc["@mozilla.org/supports-string;1"];
    var CTra = Cc["@mozilla.org/widget/transferable;1"];
    var CClp = Cc["@mozilla.org/widget/clipboard;1"];

    var str = Cstr.createInstance(Ci.nsISupportsString);
    if (!str) return false; str.data = text2copy;

    var trans = CTra.createInstance(Ci.nsITransferable);
    if (!trans) return false;

    trans.addDataFlavor('text/unicode');
    trans.setTransferData('text/unicode', str, text2copy.length * 2);

    var clipboard = CClp.getService(Ci.nsIClipboard);
    if (!clipboard) return false;

    clipboard.setData(trans, null, Ci.nsIClipboard.kGlobalClipboard);
    
    return true;
}


String.prototype.startsWith = function(str)
{return (this.match("^"+str)==str)}

String.prototype.endsWith = function(str)
{return (this.match(str+"$")==str)}

String.prototype.trim = function(){return
(this.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, ""))}
