/**
 * @namespace Holds all utility classes for the Sureflix Library
 * @uses lib/Sureflix/Sureflix.js
 * @uses lib/Prototype/Prototype.js
 * @author Hernan 12/27/2007 
 */ 
Sureflix.Utilities = {};

//Shorthand
SxUt = Sureflix.Utilities;

/**
 * @class Template Parse a given template and return the result after replacing all values with the object properties
 * @param {String} template The template to use
 * @param {String} pattern [optional] A pattern to use instead of the defaults patterns. 
 * @constructor  
 * @author Hernan 12/27/2007 based on prototype Template object  
 */ 
Sureflix.Utilities.Template = Class.create();

Sureflix.Utilities.Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
Sureflix.Utilities.Template.OldPattern = /(^|.|\r|\n)(%%(.*?)\%%)/;

Sureflix.Utilities.Template.prototype = {
  initialize: function(template, pattern) {
    this.template = template.toString();
    this.pattern  = pattern || Sureflix.Utilities.Template.Pattern;
    this.oldPattern = pattern || Sureflix.Utilities.Template.OldPattern;
  },

  /**
   * Returns the template after replacing the pattern with the object properties
   * @param {Object} object The object with the data
   * @return {String}      
   */     
  evaluate: function(object) {
  	if(!object){
		return this.template;
	}
    var tmpMatch = this.template.gsub(this.pattern, function(match) {
      var before = match[1];
      if (before == '\\') return match[2];
				if (match[3].indexOf(".") > -1){
      				var oMatch = match[3].split(".");
      				return before + String.interpret(object[oMatch[0]][oMatch[1]]);
				}      
      return before + String.interpret(object[match[3]]);
    });
    
    this.template = tmpMatch;
    tmpMatch = this.template.gsub(this.oldPattern, function(match) {
      var before = match[1];
      if (before == '\\') return match[2];
				if (match[3].indexOf(".") > -1){
      				var oMatch = match[3].split(".");
      				return before + String.interpret(object[oMatch[0]][oMatch[1]]);
				}      
      return before + String.interpret(object[match[3]]);
    });
    return tmpMatch;
  }
}

/**
 * Determines if an object is of date type
 * @param {Object} obj The object we want to test
 * @return {Boolean} Whether the object is of date type
 * @author Amy 03/07/32008
 */
Sureflix.Utilities.IsJavascriptDateType = function (obj)
{
	var isDateType = false;
	
	if(obj && typeof obj == "object"){
		if(obj.constructor.toString().indexOf("function Date()") > -1){
			isDateType = true;
		}
	}
	
	return isDateType;
}

//ram cache of cookies set in the current session
Sureflix.Utilities.cookieCache = new Hash();

/**
 * Sets a cookie with the given name and value.
 * @param {String} cookieName The name of the cookie to set
 * @param {String} cookieValue The value to set
 * @param {Date} expirationDate When to expire the cookie (optional, default is 1 year)
 * @example	SetCookie("TestCookie", "ABCDEFG");   //<A href=http://alpha.sureflix.com/work/ClientSamples/SetGetCookie.htm target=_blank>sample code</A>
 * @author Amy 10/27/2006
 */
Sureflix.Utilities.SetCookie = function(cookieName, cookieValue, expirationDate) {
	var hrefArray = document.location.href.split("/");
	var domain = hrefArray[2];
	domain = domain.replace("www.", "");
	var web = hrefArray[3];

	Sureflix.Utilities.ClearCookie(cookieName);

	var d;

	if (expirationDate && Sureflix.Utilities.IsJavascriptDateType(expirationDate)) {
		d = expirationDate;
	} else {
		d = new Date();
		//safari doesn't calculate addition right if adding 14 months, have to 
		//use 1 year, MUST use getFullYear to return 4 digits, getYear is a known bug in FF
		d.setYear(d.getFullYear() + 1);
	}
	var fullyQualifiedName = SxUt.urlEncode((domain + cookieName).toLowerCase());
	var expires = ";expires=" + d.toGMTString();
	var cookieString = fullyQualifiedName + "=" + escape(cookieValue) + "; path=/" + web + "/" + expires;
	document.cookie = cookieString;

	if (expirationDate >= new Date()) Sureflix.Utilities.cookieCache.set(cookieName, cookieValue.toString());
}


/**
 * Clear the cookie with the given name
 * @param {String} cookieName The name of the cookie to clear
 * @example ClearCookie("TestCookie");   //<A href=http://alpha.sureflix.com/work/ClientSamples/SetGetCookie.htm target=_blank>sample code</A>
 * @author Erik 08/11/2008
 */
Sureflix.Utilities.ClearCookie = function(cookieName) {
	var hrefArray = document.location.href.split("/");
	var domain = hrefArray[2];
	domain = domain.replace("www.", "");
	var web = hrefArray[3];

	var killDate = new Date("January 1, 1970");
	var killString = cookieName + "=; path=/" + web + "/;expires=" + killDate.toGMTString();
	document.cookie = killString;

	var fullyQualifiedName = SxUt.urlEncode((domain + cookieName).toLowerCase());
	killString = fullyQualifiedName + "=; path=/" + web + "/;expires=" + killDate.toGMTString();
	document.cookie = killString;

	Sureflix.Utilities.cookieCache.unset(cookieName);
}


/**
* Get the cookie with the given name
* @param {String} cookieName The name of the cookie to get
* @return {String} The value of the cookie or undefined
* @example GetCookie("TestCookie");
* @author Erik 08/11/2008
*/
Sureflix.Utilities.GetCookie = function(cookieName) {
	if (!cookieName) return "";
	var cachedCookie = Sureflix.Utilities.cookieCache.get(cookieName);
	if (cachedCookie != undefined) return cachedCookie;

	var hrefArray = document.location.href.split("/");
	var domain = hrefArray[2];
	domain = domain.replace("www.", "");

	var fullyQualifiedName = SxUt.urlEncode(domain + cookieName);
	var re = new RegExp('\\b' + fullyQualifiedName + '\\b=(.*?)(;|$)', 'i');
	var results = document.cookie.match(re);

	if (!results) {
		re = new RegExp('\\b' + cookieName + '\\b=(.*?)(;|$)', 'i');
		results = document.cookie.match(re);
	}

	if (!results) {
		return "";
	} else {
		return unescape(results[1]);
	}
}

/**
 * Removes a copyright symbol (and leading spaces) from text.
 * @param {String} text The text that contains a copyright symbol
 * @return {String} The string without the copyright.
 * @example	StripCopyright(escape($("MyFormField").value));	
 * @author Amy 05/21/2008
 */
Sureflix.Utilities.StripCopyright = function(text){
	text = text || "";
	var re = new RegExp("(\&copy;|\u00A9|\%A9)*", "gi");
	text = (text.replace(re, "")).replace(/^(\s|\%20)*/, "");
	return text;
}

/**
 * Appends the html code for a copyright symbol and a space to the front of text.
 * @param {String} text The text that contains a copyright symbol
 * @return {String} The string without the copyright.
 * @author Amy 05/22/2008
 */
Sureflix.Utilities.AppendCopyright = function (text) {
	text = text || "";
	return "&#169; " + text;
}

/**
 * Gets the property value for a given object if the property exists
 * @param {Object} obj The object that we want to get the property from
 * @param {String} propertyName The name of the property
 * @param {String} defValue The default value if the property doesn't exist, 
 * optional - the default is null
 * @return {String} The value of the property or the default value.
 * @author Amy 06/09/2008
 */
Sureflix.Utilities.getPropertyValue = function (obj, propertyName, defValue) {
	var propertyValue = null;
	try{
		//if(obj && obj[propertyName]){
			propertyValue = obj[propertyName];
		//}
	}catch(e) {
		Sureflix.Error.ErrorHandler.consoleError(e);
	}
	
	if (!propertyValue && propertyValue != false){
		propertyValue = null;
	}
	
	if (propertyValue == null && defValue != undefined){
		propertyValue = defValue;
	}
	return propertyValue;
}

/**
 * Gets the method value for a given object if the method exists
 * @param {Object} obj The object that we want to get the method from
 * @param {String} methodName The name of the method
 * @param {String} defValue The default value if the method doesn't exist, 
 * optional - the default is null
 * @return {String} The value of the method or the default value.
 * @author Amy 06/09/2008
 */
Sureflix.Utilities.getMethodValue = function (obj, methodName, defValue) {
	var methodValue = null;
	try{
		//if(obj && obj[methodName]){
			methodValue = obj[methodName]();
		//}
	}catch(e) {
		Sureflix.Error.ErrorHandler.consoleError(e);
	}
	
	if (!methodValue && methodValue != false){
		methodValue = null;
	}
	
	if (methodValue == null && defValue != undefined){
		methodValue = defValue;
	}
	return methodValue;
}

/**
 * Tests if two or more objects are equal, accepts any type of object, even multidimensional arrays.
 * @param {Object} a The first object to compare
 * @param {Object} b The second object to compare
 * @return {Bool} Whether or not the objects are equal
 * @author Jonas Raoni Soares Silva  Created: 2005.12.26 
 * @ http://jsfromhell.com/geral/equals [v1.0]
 */
Sureflix.Utilities.areEqual = function(a, b){
    for(var j, o = arguments, i = o.length, c = (typeof a === "object"); --i;)
        if(a === (b = o[i]))
            continue;
        else if(!c || !(typeof b === "object"))
            return false;
        else for(j in b)
            if(!Sureflix.Utilities.areEqual(a[j], b[j]))
                return false;
    return true;
}


/**
 *	Check for an empty string or null or undefined
 *	@param _value: The value to check.
 *	@returns: True if is empty, false if it isn't
 */
Sureflix.Utilities.isEmpty = function(_value) {
	if (!_value) return true;
	
	var thisVal = _value.toString().toLowerCase();

	if (thisVal == "" || thisVal == "null" || thisVal == "undefined") {
		return true;
	}
	return false;
}

/**
*	Returns an xml nodes text or textContent
*	@param node: The xml node that we want the text from
*	@returns: The nodes text or textContent
*/
Sureflix.Utilities.getXmlNodeText = function(node) {
    return (node.text || node.textContent);
}

/**
* Adds/Edits/Removes a parameter from a query string.
* @param {String} qsString The entire URL or just the qs portion (starting with '?')
* @param {String} qsKey The name of the parameter to edit, case insensitive
* @param {String} qsValue The new value to assign to the parameter; removes all instances if omitted; adds parameter if it doesn't exist
* @return {String} The edited string
* @example url = Sureflix.Utilities.editQSParam(url, "Category", "New"); //<A href=http://alpha.sureflix.com/work/ClientSamples/EditQSParam.htm target=_blank>sample code</A>
* @author Amy 10/24/2006
*/
Sureflix.Utilities.editQSParam = function(qsString, qsKey, qsValue) {
	var NewQS = qsString;
	var MyRegex = new RegExp("(([\\?\\&]*" + qsKey + "=)([^\\?\\&\\s\\#]*))", "gi");

	// check if the qs contains the parameter
	if (MyRegex.test(NewQS)) {
		// remove all instances of the parameter
		NewQS = NewQS.replace(MyRegex, "");

		// if there are no ? then replace first & with ? to form a proper querystring
		if (NewQS.indexOf("\?") == -1) {
			NewQS = NewQS.replace("\&", "\?");
		}
	}

	// if we're editing, add the new value
	if (qsValue) {
		qsValue = qsValue + "";
		var AnchorString = "";
		// if the QS contains an anchor, insert the new param before the anchor
		if (NewQS.indexOf("#") != -1) {
			AnchorString = NewQS.substring(NewQS.indexOf("#"));
			NewQS = NewQS.substring(0, NewQS.indexOf("#"));
		}
		NewQS = NewQS + (NewQS.indexOf("\?") == -1 ? "?" : "&") + qsKey + "=" + qsValue + AnchorString;
	}

	// remove double && with &
	NewQS = NewQS.replace(/\&\&/gi, "\&");

	return NewQS;
}

Sureflix.Utilities.getQSParam = function(key, default_) {
	if (default_ == null) default_ = "";
	
	key = key.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
	var regex = new RegExp("[\\?&]" + key + "=([^&#]*)", "i");
	var qs = regex.exec(window.location.search);
	if (qs == null)
		return default_;
	else
		return qs[1];
}

Sureflix.Utilities.copyInputText = function(input) {
	input = $(input);
	input.focus();
	input.select();
	inputText = input.value;
	
	try {
		window.clipboardData.setData("text", inputText);
	} catch (e) {
		window.alert(Sureflix.Phrases.BrowserCopy_);
	}
}


/**
* Gets text content from any url
* @param {String} webServiceUrl
* @author Erik 21/12/2009
*/
Sureflix.Utilities.getTextFromUrl = function(webServiceUrl) {
	var result = null;

	new Ajax.Request(
		webServiceUrl, {
			method: 'GET',
			asynchronous: false,
			onSuccess: function(transport) {
				result = transport.responseText;
			}
		}
	);

	return result;
}


/**
* Converts the input to a string, padding it with the given character
* @param {Object} input
* @param {String} pad The padding character(s)
* @param {String} length The desired length of the output string
* @author Erik 09/01/2010
*/
Sureflix.Utilities.padString = function(input, pad, length) {
	var paddedString = input.toString();

	while (paddedString.length < length) {
		paddedString = pad + paddedString;
	}

	if (paddedString.length > length) {
		paddedString = paddedString.substr(paddedString.length - length);
	}

	return paddedString;
}


/**
* URL encodes the given string
* @param {String} input
* @author Erik 09/02/2010
*/
Sureflix.Utilities.urlEncode = function(input) {
	return escape(input).replace(/\+/g, '%2B').replace(/\"/g, '%22').replace(/\'/g, '%27').replace(/\./g, '%2E');
}


/**
* Returns the source of the current page (without the host) URL encoded
* @author Erik 09/02/2010
*/
Sureflix.Utilities.getEncodedSource = function() {
	var source = document.location.pathname + document.location.search;
	source = SxUt.editQSParam(source, "Q", "");
	return Sureflix.Utilities.urlEncode(source);
}