/* 	Copyright 2008 Maximum Processing Inc
	This script provides commonly used utility functions

	ABOUT THIS SCRIPT

	DEPENDENCIES
	  1. logging.js

	
	Change Log
 	Created 11/19/2008 Nathan Townsend
 	11/20/2008 - added jQuery.fn.outerHTML for cross browser compatibility
 	11/22/2008 - added logging NT
*/


/* EXAMPLE USAGE
var arr = new Array();
arr[0] = ["name", "value"];	 	 					 <option value='value'>name</option>
arr[1] = ["name2", "value2", "title"];	 <option value='value2' title='title'>name2</option>		
alert(arr.ToOptions()); */
Array.prototype.ToOptions = function()
{
  try{
	  var opts = "";
    for(var i = 0; i<this.length; i++)
  	{
  	  var opt = this[i];
  		switch(typeof opt)
  		{
  		  case "string":
  	      opts += "<option value='" + opt + "'>" + opt + "</option>";
  			  break;
  				
  			case "object":
  			  switch(opt.length)
  				{
  				  case 2:
  					  opts += Utilities.Format("<option value='{1}'>{0}</option>", opt);
  						break;
  					case 3:
  					  opts += Utilities.Format("<option value='{1}' title='{2}' >{0}</option>", opt);
  						break;
  					case 4:
  					  opts += Utilities.Format("<option value='{1}' title='{2}' {3}>{0}</option>", opt);
  						break;							
  				}
  			  break;
  		}
  	}
		
		return opts;
		
  }catch(err){ if(Log){Log.Add("Array.ToOptions", err, LogType.Error)}; throw err;}	
}

Array.prototype.reset = function()
{ 
  for(var i = 0; i<this.length; i++)
	  this[i] = null;
		
	//this = new Array();	
}


Array.prototype.toPipeString = function()
{ 
  var str = "";
  for(var i = 0; i<this.length; i++)
	{
    str += this[i] + "|";
	}
	
	return str.substring(0, str.length-1);
	
}

String.prototype.beginsWith = function(str)
{
  var L = str.length;
	
  var begin = this.substring(0, L);
	
	return (begin == str);
}

String.prototype.endsWith = function(str)
{
  var L = str.length;
	
  var end = this.substring(this.length - L);
	
	return (end == str);
}

String.prototype.removeLastChar = function()
{
  return this.substring(0, this.length-1);
}

String.prototype.removeFirstChar = function()
{
  return this.substring(1);
}

String.prototype.insert = function(position, str)
{
  if(typeof position == "object")
	{
	  var ret = "";
		var lp = 0;
	  for(var i = 0; i<position.length; i++)
		{
		  var p = position[i];
			ret+= this.substring(lp, p) + str;
			lp = p;
		}
		ret += this.substring(lp);
		return ret;
	}
	
  return this.substring(0, position) + str + this.substring(position);
}


// add the outerHTML function to jQuery
jQuery.fn.outerHTML = function() {
  try{
    
    if(this[0].outerHTML)
      return this[0].outerHTML;
    
    // TODO: if not IE then this code must return the equivalent of outerHTML - needs testing
    return $('<div>').append( this.eq(0).clone(true) ).html();
  
  } catch(err){ Log.Add("jQuery.fn.outerHTML", err, LogType.Error)};
};




Utilities = new function()
{
  try{
  
  /* Public Methods */
  return{
    
    CleanHTML: function(html)
    {
      try{
        var start = html.indexOf("jQuery");

        var end = html.indexOf("\"", start);
				
        end = html.indexOf("\"", end + 1);
      
        var rep = html.substring(start, end + 1);
      
        html = html.replace(rep, "");
        
        if(html.indexOf("jQuery") > -1)
          return this.CleanHTML(html); 
      
        return html; 
        
      } catch(err){ Log.Add("Utilities.CleanHTML", err, LogType.Error); }
    },
		
    GetAttributes: function(elem) {
      try{
    		
				var html = GetOpeningTag($(elem).outerHTML());
				
				
				    		
    		return attributes;
				
      } catch(err){ Log.Add("Utilities.GetAttributes", err, LogType.Error); }				
    },		
    
    // formats an array for .droppable accept selector
    GetAcceptedComponents: function(AcceptArray)
    {
      try{
			
        var _accept = "";
        
        for(var i = 0; i < AcceptArray.length; i++)
          _accept += Editor.ComponentTemplateTagName + "[ref='" + AcceptArray[i] + "'],";
          
        _accept = _accept.substring(0, _accept.length - 1);
        
        return _accept;
        
      } catch(err){ Log.Add("Utilities.GetAcceptedComponents", err, LogType.Error); }
    },
    
    
    // returns the current time formatted "0h:0m:0s:00ms"
    GetFormattedTime: function()
    {
        try
        {
            var d = new Date();
        
            var t = this.PadNumber(d.getHours()) + ":" + this.PadNumber(d.getMinutes()) + ":" + this.PadNumber(d.getSeconds()) + ":" + this.PadNumber(d.getMilliseconds(), 4);
            
            return t;
        } catch(err) { Log.Add("Utilities.GetFormattedTime", err, LogType.Error); }
    },
		
		GetTimeDifference: function(Date1, Date2)
		{
		  var d1 = Date1.getTime();
			var d2 = Date2.getTime();
			return d2 - d1;
			
		},
		
    FilterScript: function(Script)
    {
      try{
        
        var s = "";
        
        for(var j =0; j<Script.length; j++)
        {
          var character = Script.substring(j, j+1);
          var code = character.charCodeAt(0);
          if(code != 10)
            s += character;
        }
        
        return s;
      
      } catch(err) { Log.Add("Utilities.FilterScript", err, LogType.Error); }
    },
    

		Format: function(str, params)
		{
		  try{
  
			  for(var i = 0; i<params.length; i++)
				{
				  str = str.replace("{" + i + "}", params[i]);
				}				
				
				return str;
	
			}catch(err){Log.Add("Utilities.Format", err, LogType.Error)}
		},

    OpeningTag: function(str){
      try{
        
    		var attrs = Utilities.GetAttributes(str);
    		
    		for(var i = 0; i<attrs.length; i++)
    		{
    		  var b = html;
    		  html = html.replace(attrs[i], "{" + i + "}");
    		}
    		
    		html = html.substring(0, html.indexOf(">")) + ">";
    		
    		return Utilities.Format(html, attrs);
    
      
      } catch(err){ Log.Add("Utilities.OpeningTag", err, LogType.Error)};
    },
		
		
		
    // pads numbers with zero to the specified length [default padding = 2]
    PadNumber: function(number, padding)
    {
        try
        {
            if(padding == null)
              padding = 2;
              
            var m = "1000000000000000";
            
            var c = "0000000000000000";
            
            var n = parseInt(m.substring(0, padding));
            
            if(number >= n)
              return number;
            
            var l = number.toString().length;
            
            var b = c.substring(0, padding - l);
            
            return b + number.toString();
            
        } catch(err) { Log.Add("Utilities.PadNumber", err, LogType.Error); }
    },
		
		ParseXML: function( xml ) { 
        if( window.ActiveXObject && window.GetObject ) { 
            var dom = new ActiveXObject( 'Microsoft.XMLDOM' ); 
            dom.loadXML( xml ); 
            return dom; 
        } 
        if( window.DOMParser ) 
            return new DOMParser().parseFromString( xml, 'text/xml' ); 
        throw new Error( 'No XML parser available' ); 
    },
		
    
    
    
    
    PreventRefresh: function()
    {
      try{

        document.oncontextmenu = nocontextmenu;
       
        document.onmousedown = norightclick;
       
        document.attachEvent("onkeydown", onKeyDown);
       
        var oLastBtn=0;
       
        bIsMenu = false;
       
        if (window.Event)
          document.captureEvents(Event.MOUSEUP);
          
      } catch(err){ Log.Add("Utilities.PreventRefresh", err, LogType.Error); }
    
    },
    
    // prompts the user for a control name and ensures it doesn't already exist
    PromptForName: function(boolUnique, caption)
    {
      try{

        var name = "";
				
				if(caption == null)
          name = prompt("Please enter the control name", "");
				else
          name = prompt(caption, "");			  
      
        if(name == "" || name == null)
          Log.Add("Utilities.PromptForName", "the name entered was invalid", LogType.Error);
      
        if(boolUnique)
        {
          if( $("#" + name).length > 0 )
            Log.Add("Utilities.PromptForName", "the name entered is already being used", LogType.Error);
        }
      
        return name;  
        
      } catch(err){ Log.Add("Utilities.PromptForName", err, LogType.Error); }      
    },

    
    ReplaceAll: function (str, find, val)
    {
      try{
          if(str == null)
					  return null;
						
					if(typeof str != "string")
					  return "";
						
          while(str.indexOf(find) > -1 )
          {
            str = str.replace(find, val);
          }

          return str;
      } catch(err){ Log.Add("Utilities.ReplaceAll", err, LogType.Error); }
    },
    
    Serialize: function(HTML)
    {
      try{

        var toReturn    = [];
        var els         = $(HTML).find(':input').get();
        
        $.each(els, function() {
            if (this.name && !this.disabled && (this.checked || /select|textarea/i.test(this.nodeName) || /text|hidden|password/i.test(this.type))) {
                var val = $(this).val();
                toReturn.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( val ) );
            }
        }); 
				
				// Gets the FCK Editor html 
				$(HTML).find("div[ref='EditorMemo']").each(function(){
					if($(this).attr("EditHTML") == "true")
					{
					  var id = $(this).find("textarea").attr("id");
						var oEditor = FCKeditorAPI.GetInstance(id);
						var html = encodeURIComponent(oEditor.GetHTML());
						for(var i = 0; i<toReturn.length; i++)
						{
						  if(toReturn[i].beginsWith(encodeURIComponent(id)))
							  toReturn[i] = id + "=" + html;
						}
					}
				});

        var ret = toReturn.join("&").replace(/%20/g, "+");
				
				ret += TransferListHelper.Serialize(HTML);  // serialize the transfer lists
				
				return ret;
                
        
        
      } catch(err){ Log.Add("Utilities.Serialize", err, LogType.Error); }
        
    },
		
		SortSelect: function(sel)
		{
		  try{

        sel = $(sel)[0];
				
				for(var i = 0; i<sel.options.length; i++)
				{
				  var a = sel.options[i];
					
					var move = true;
					
  				for(var j = 0; j<sel.options.length; j++)
					{
					  if(j != i && move == true)
						{
					    var b = sel.options[j];
							
							if($(a).text() < $(b).text())
							{
							  $(a).remove().insertBefore($(b));
								move = false;							
							}
						}					
					}					
				}

      } catch(err){ Log.Add("Utilities.SortSelect", err, LogType.Error); }		
		},
    
    
    ToNumber: function(str)
    {
   
        try
        {
      
          if(typeof str == "number")
            return str;
      
          if(str.indexOf('px')>-1)
          {
            var ret = str.replace('px', '');
      
            return parseInt(ret);
          }
      
          if(str.indexOf('auto')>-1)
          {
            Log.Add("Utilities.ToNumber", "str contained 'auto' so zero was returned", LogType.Warning)
            return 0;
          }
      
          if(str.indexOf('none')>-1)
          {
            Log.Add("Utilities.ToNumber", "str contained 'none' so zero was returned", LogType.Warning)
            return 0;
          }
      
          if(str.indexOf('medium')>-1)
            return 0;
          
          Log.Add("Utilities.ToNumber", "attempting to return parseInt(" + str + ")", LogType.Warning);

          return parseInt(str);
        
       } catch(err){ Log.Add("Utilities.ToNumber", err, LogType.Error); }
   
    },
		
    // Reads the properties of an object and displays them as name = value pairs
    ToString: function(IComponent, wrapped) 
    {
      try{
			
			  var _str = "";
      
        if(!wrapped)
          _str = "{\n";

        
        jQuery.each(
          IComponent, 
          function(field, value)
          { 
            if(Utilities.IsObject(value))
              _str +=  "\"" + field + "\": {\n" + Utilities.ToString(value, true) + "\n},"; 
            else
						{
						  switch(typeof value)
							{
							  case "boolean":
    							_str += "\"" + field + "\":" + value + ",";								  
								  break;
									
								case "string":
  								_str += "\"" + field + "\":\"" + value + "\",";
								  break;
																	
								case "number":
	  							_str += "\"" + field + "\":" + value + ",";							
								  break;
																	
								default:
    							_str += "\"" + field + "\": \"" + value + "\",";
									break;
							}
							_str += "\n";
						} 
          }
         );
        
				if(!wrapped)
				  _str += "\n}";
					
				_str = _str.replace(/,\s{0,}\}/g, "\n}");
				
        return _str;
    
      } catch(err){ Log.Add("Utilities.ToString", err, LogType.Error); }
    },
		
		Trim: function(str)
		{
		  return str.replace(/^\s+|\s+$/g,"");
		},
    
    // returns true if o is an object
    IsObject: function(o) 
    {
      try{
        return (o && "object" == typeof o) || Utilities.IsFunction(o);
      } catch(err){ Log.Add("Utilities.IsObject", err, LogType.Error); }    
    },
        
    
    
    // returns true if o is a function
    IsFunction: function(o) 
    {
      try{
        return "function" == typeof o;
      } catch(err){ Log.Add("Utilities.IsFunction", err, LogType.Error); }
    },
    
    IsNumber: function(o)
    { 
      try{
        return "number" == typeof o; 
      } catch(err){ Log.Add("Utilities.IsNumber", err, LogType.Error); }
    }
    
  }
  
	

  
  
  
  
    /* Prevent Page Refresh Helper */
    function nocontextmenu()
    {
      try{
      
        event.cancelBubble = true
        event.returnValue = false;
        return false;
        
      } catch(err){ Log.Add("Utilities.nocontextmenu", err, LogType.Error); }
    }
    
    
    function norightclick(e)
    {
      try{
      
          if (window.Event)
          {
            if (e.which !=1)
            return false;
          }
          else

          if (event.button !=1)
          {

            event.cancelBubble = true

            event.returnValue = false;

            return false;
          }
      } catch(err){ Log.Add("Utilities.norightclick", err, LogType.Error); }
    }
    
    
    function onKeyDown() 
    {
      try{

    
          //if ((event.altKey) || ((event.keyCode == 8) ||((event.ctrlKey) && ((event.keyCode == 78) || (event.keyCode == 82))) || (event.keyCode == 116)||(event.keyCode == 122)))
          if (
						   (event.altKey) || (
							   (event.ctrlKey) && (
								   (event.keyCode == 78) || (event.keyCode == 82)
								  )
							 || (event.keyCode == 116)||(event.keyCode == 122))
							)

          {
            event.keyCode = 0;
            event.returnValue = false;
          }
      } catch(err){ Log.Add("Utilities.onKeyDown", err, LogType.Error); }
    }
    /* End Prevent Page Refresh Helper */
  
  
  

 } catch(err){ Log.Add("Utilities", err, LogType.Error); }
}















function HTMLParser(element){

  var _elem = $(element);
	
	var _html = _elem.outerHTML();
	
	
	
	this.GetSRAttrs = function(){
	  try{
  
  	  var ot = this.GetOpeningTag();
  		 
			if(ot == null)
			  return;
			
  		if(ot.indexOf("#") == -1)
  		  return "";
  		
  	  ot = ot.substring(ot.indexOf(" "));		 // get rid of opening tag
  
      var exp = /[#][^#]+[#]/g;
      
      var mc = ot.match(exp);
      
  		var ret = "";
  		
  		if(!mc)
  		  return ret;
  		
  		for(var i = 0; i<mc.length; i++)
  		  ret += mc[i] + " ";
  		
  		return ret;	
			
    }catch(err){Log.Add("HTMLParser.GetSRAttrs", err, LogType.Error);}			  
	}
	
	
  this.GetValuelessAttributes = function(){
    try{
  	
		  var attrList = ["disabled", "readonly", "checked"];
			
			var _ret = "";
			
			for(var i = 0; i < attrList.length; i++)
			{
			  var att = attrList[i]; 
				
			  if(_elem.attr(att))
				  _ret += att + " ";

			}
			
			_ret += this.GetSRAttrs();
			
			_ret = Utilities.ReplaceAll(_ret, "  ", " ");
			
			_ret = Utilities.ReplaceAll(_ret, " ", ",");
			
			_ret = Utilities.ReplaceAll(_ret, ",,", ",");
			
			if(_ret.endsWith(","))
			  _ret = _ret.removeLastChar();
				
			if(_ret.beginsWith(","))
			  _ret = _ret.removeFirstChar();
												
			return _ret.split(",");	
		
    }catch(err){Log.Add("HTMLParser.GetValuelessAttributes", err, LogType.Error);}
	}	
	
	
	this.GetOpeningTag = function(){
	  try{
		
  	  var _esc = /\w+=[\"'][^\"']+[\"']/g;
  		
  		var matches = _html.match(_esc);
  		
  		var temp = _html;
			
			if(matches == null)
			  return;
				
  		for(var i = 0; i < matches.length; i++)
  		{
  		  var m = matches[i];
  			
  			if(m.indexOf(">") > -1)
  			  temp = temp.replace(m, m.replace(">", "||&gt;||"));
  		}
			  		
  		var ot = temp.substring(0, temp.indexOf(">"));
  		
  		_openingTag = ot.replace("||&gt;||", ">") + ">";
			
  		
  		return _openingTag;
			
    }catch(err){Log.Add("HTMLParser.GetOpeningTag", err, LogType.Error);}			
	}
	

		
}
