/* 	Copyright 2008 Maximum Processing Inc
	This script runs the properties editor

	Change Log
 	Created 12/03/2008 Nathan Townsend
*/




PropertiesEditor = new function()
{
  
	var _div = null;
	var _height = 400;
	var _width= 300;
	var _top = 0;
	var _left = 0;
	var _coords = ['right', 'bottom', 300, 400];
	var _complexPropertyIndex = 0;
	var _savedProperties = null;
	var _deleteCallback = null;
	var _scroll = 0;

	return{
	
	  Initialize: function(PropertiesDiv)
		{
		  try{

  		  _div = $(PropertiesDiv);
  				
		  	this.Hide();
			
		  } catch(err){ Log.Add("PropertiesEditor.Initialize", err, LogType.Error); }
			
		},
		
		DeleteComponent: function()
		{
		  try{
			
  		  _deleteCallback();
	  		this.Hide();
				
      } catch(err){ Log.Add("PropertiesEditor.DeleteComponent", err, LogType.Error); }
		},
		
		Disable: function()
		{
		  try{
			
 		  	Editor.DisableEditor();
 	  		RulesMaker.Disable();
  		  PropertiesEditor.Hide();
				$("#EditVRMButton").removeAttr("disabled");
				$("#EditorNotes #save").attr("disabled", "true");
				
				ContextMenu.RemoveAll();
				
				Communication.CloseEditor();
				
      } catch(err){ Log.Add("PropertiesEditor.Disable", err, LogType.Error); }			
		},
	
		
	  Hide: function()
		{
		  try{
			
				StationaryDivs.Current.Minimize();
				
      } catch(err){ Log.Add("PropertiesEditor.Hide", err, LogType.Error); }			
		},		
		
    Property: function(Item, Get, Set, Args)
    {
       try{
          
          this.Item = Item;
          this.Get = Get;
          this.Set = Set;
          this.Args = Args;
          
       } catch(err){ Log.Add("PropertiesEditor.Property", err, LogType.Error); }
    },
		
		Show: function(properties, DeleteCallback, PropertyEditorTitle)
		{
		  try{
		    if(event != null) 
				{
				  if(event.srcElement != null)
					{
					  Global.EditingTemplate = ($(event.srcElement)[0].tagName == "DIV");
					}
				}			
			
  		  _deleteCallback = DeleteCallback;
  		
  		  _savedProperties = properties; 
  			
  		  _complexPropertyIndex = 0;
  		
  		  var table = GeneratePropertiesTable(properties);
  
  			this.SetTable(table);

				StationaryDivs.Current.Restore();
				
				StationaryDivs.Current.SetTitle(PropertyEditorTitle);
				
				_div.find(".PropertyEditorTable").find("textarea").resizable({ autoHide: true, knobHandles: true, transparent: true });				
				
		  } catch(err){ Log.Add("PropertiesEditor.Show", err, LogType.Error); }
		},
		
		Saving: false,
		
		
    ShowMessage: function(message, autoHide)
    {
      try{
    
          if(autoHide == null)
            autoHide = true;
          
          _div.find("#Message").text(message);
        
          if(autoHide)
            _div.find("#Message").fadeIn(1000, function(){ PropertiesEditor.HideMessage() });
          else
            _div.find("#Message").fadeIn(1000);
            
      } catch(err){ Log.Add("PropertiesEditor.ShowMessage", err, LogType.Error); }
    },
		
    HideMessage: function()
    {
      try{
         _div.find("#Message").fadeOut(3000);
      } catch(err){ Log.Add("PropertiesEditor.HideMessage", err, LogType.Error); }
    },
		
		Save: function()
		{
		  try{
			
			  PropertiesEditor.Saving = true;
			
			  this.Disable();
				
				var notes = Global.GetNotes();
				
				RuleXML.SetEditorNotes(notes);				
  		
			  Communication.EditorUpdate();
				
				Global.DisableNotes();
			
				this.Hide();
				
			  PropertiesEditor.Saving = false;
				
			} catch(err){
			
			  Global.ShowMessage("<h3>PropertiesEditor.Save</h3><p>An error has occured. Please diagnose the problem using the information found in the 'Ajax' and 'Logging' tabs.</p>"); 
			
			  Log.Add("PropertiesEditor.Save", err, LogType.Error);
			
			}
		},
		
		GetDiv: function(){
		  return _div;
		},
		
		GetTable: function()
		{
		  try{
  		  return _div.find(".PropertyEditorTable");
		  } catch(err){ Log.Add("PropertiesEditor.GetTable", err, LogType.Error); }
		},
		
		GetHeight: function()
		{
		  try{
  		  return _div.find(".PropertyEditorTable").outerHeight();
		  } catch(err){ Log.Add("PropertiesEditor.GetHeight", err, LogType.Error); }		  
		},		
		
		GetWidth: function()
		{
		  try{
  		  return _div.find(".PropertyEditorTable").outerWidth();
		  } catch(err){ Log.Add("PropertiesEditor.GetWidth", err, LogType.Error); }		  
		},
		
		SetTitle: function(newTitle)
		{
		  try{
  		  _div.attr("title", newTitle);
			} catch(err){ Log.Add("PropertiesEditor.SetTitle", err, LogType.Error); }
		},
		
		SetHeight: function(height)
		{
		  try{
  		  _height = height;
				_div.css("height", _height);
			} catch(err){ Log.Add("PropertiesEditor.SetHeight", err, LogType.Error); }
		},
		
		SetWidth: function(width)
		{
		  try{
  		  _width = width;
				_div.css("width", _width);
			} catch(err){ Log.Add("PropertiesEditor.SetWidth", err, LogType.Error); }
		},		
				
		UpdateProperties: function()
		{
		  try{
			
		    _complexPropertyIndex = 0;
			 
  			 SaveProperties(_savedProperties, $(this.GetTable()) );
				 
				 Graphics.Refresh();

  		} catch(err){ Log.Add("PropertiesEditor.UpdateProperties", err, LogType.Error); }		
		},
		
		SetTable: function(table)
		{
		  try{
			
  		  var p = _div.find(".PropertyEditorTable");
	  		table.addClass(p.attr("class"));
		  	p.replaceWith(table);
			} catch(err){ Log.Add("PropertiesEditor.SetTable", err, LogType.Error); }
		},
		
		SetWidth: function(width)
		{
		  try{
  		  _width = width;
			} catch(err){ Log.Add("PropertiesEditor.SetWidth", err, LogType.Error); }
		}
	  
  }
	
	
	
	
	
	/* Private functions */
	function GeneratePropertiesTable(properties)
  {
    try{
        var urlparts = window.location.href.split('/');
        var host_url = urlparts[0] + '/' + urlparts[1] + '/' + urlparts[2];
        var host_fix = new RegExp(host_url, "g");

    
        var table = $("<table class='properties'/>");
        
        for(var i = 0; i < properties.length; i++)
        {
          var tr = $("<tr/>");
          
  				var th = $("<th/>").text(properties[i].Item.Caption);
          
          tr.append(th);
          
          var input = null;
          
          switch(properties[i].Item.Type)
          {
            case "text":
              input = $("<textarea />");
              input.val(properties[i].Get());
		  input.attr("title", properties[i].Item.Description);
              //URL fix for the URL in the path...
              input.val(input.val().replace(host_fix, "../.."));
              break;
            
            case "checkbox":
              var checked = properties[i].Get() ? "checked" : "";
              input = $("<input type='checkbox' " +  checked + "/>");
							input.attr("title", properties[i].Item.Description);
              break;
            
            case "select":
              var options = properties[i].Args;
              var selected = properties[i].Get();
              input = $("<select />");
							/*
              for(var j = 0; j<options.length; j++)
              {
                if(options[j] == selected)
                  input.append($("<option selected value='" + options[j] + "'>" + options[j] + "</option>"));
                else
                  input.append($("<option value='" + options[j] + "'>" + options[j] + "</option>"));
              }
							*/
							var opts = options.ToOptions();
							input.html(opts);
							input.val(selected);
		          input.attr("title", properties[i].Item.Description);
							break;
						
						case "complex":
							input = CreateComplexInput(properties[i]);
						  break;
							
						case "memo":
						  input = $("<textarea class='PropertyTableMemo'/>"); 
							input.val(properties[i].Get());
							input.attr("title", properties[i].Item.Description);
							break;
          }
          
          input.attr("id", "propertyeditor" + properties[i].Item.ID);
          
          if(properties[i].Set == null)
            input.attr("disabled", "true");
          
          var td = $("<td/>").html(input);
          
          tr.append(td);
          
          table.append(tr);
        }
        
        return table;
    
    } catch(err){ Log.Add("PropertiesEditor.GeneratePropertiesTable", err, LogType.Error); }
  }	
	
	
	function CreateComplexInput(property)
	{
	  try{
		
    	  var table = $("<table/>");
    		
    		captions = property.Item.Description.split("|");
				
    	  var tr = $("<tr/>");
				
    		for(var i = 1; i<captions.length; i++)
    		{
				  var capt = captions[i];
					
					if(capt.indexOf("[") > -1)
					  capt = capt.substring(0, capt.indexOf("["));
					
    		  var th = $("<th/>").text(capt);
    			tr.append(th);		  
    		}
    		
    		table.append(tr);
    
    		var params = property.Get();
				
				var complexArgs = property.Args;
    
    		for(var i = 0; i<params.length; i++) // loops through each parameter in an array of parameters such as several params in a select
    		{
    
    		  var tr = $("<tr/>");
    			
    			var param = params[i];
					
					var noDisplay = 100;
          
					var captIndex = 0;
    			jQuery.each(param, function(field, value){ // loops through each field in a complex property such as name, type, value for a select param
					  _complexPropertyIndex++;
						captIndex++;

      			var td = $("<td/>");
	  				var inpt = GetComplexInput(value, captions[captIndex]);

				  	inpt.attr("id", _complexPropertyIndex);
						
   			  	td.append(inpt);
   				  tr.append(td);
    			});
					
					var td = $("<td><img src='../../images/deleteparam.png' alt='Delete this row' style='cursor:pointer;' /></td>");
				  var img = td.find("img");
					img.attr("paramIndex", i);
				  img.click(function(){PropertiesEditor.UpdateProperties(); complexArgs.DeleteParam(parseInt($(this).attr("paramIndex"))); if(!Global.EditingTemplate){ RulesMaker.RefreshProperties();} });

					tr.append(td);
    			
    			table.append(tr);
					
    		}
				
				var tr = $("<tr/>");
				for(var cl = 1; cl<captions.length; cl++)
				  tr.append($("<td>&nbsp;</td>"));
				
				
        var td = $("<td><img src='../../images/addparam.png' alt='Add a new row' style='cursor:pointer;' /></td>");
			  var img = td.find("img");
			  $(img).click(function(){PropertiesEditor.UpdateProperties(); complexArgs.AddParam(); RulesMaker.RefreshProperties(); });
    		tr.append(td);
				table.append(tr);

				
    		return table;
				
    } catch(err){ Log.Add("PropertiesEditor.CreateComplexInput", err, LogType.Error); }				
	}
	

	function GetComplexInput(value, capt)
	{
	  try{
		
			var start = capt.indexOf('[');

			var stop = capt.indexOf(']');

			if((start == -1) && (stop == -1))
			  return $("<textarea />").val(value);
			
		  var str = capt.substring(start + 1, stop);

			var type = str.substring(0, str.indexOf(":"));
			
	    var opts = str.substring(str.indexOf(":") + 1).split(",");
		
		  var noDisplay = null;
		
			switch(type)
			{
			  case "select":
				  var inpt = $("<select />");
    			for(var i = 0; i<opts.length; i++)
    			{
					  
						var optText = Utilities.Trim(opts[i]);
						
						/*
						noDisplay = optText.match(/\(\d{1,}\)/);
						
						if(noDisplay)
						{
						  optText = optText.replace(noDisplay.toString(), "");
						  noDisplay = parseInt(noDisplay.toString().match(/\d{1,}/));
							//alert("text: " + optText + "\n\ndisplay: " + noDisplay);
						}
						*/
						
					  var opt = $("<option value='" + optText.toUpperCase() + "'>" + optText + "</option>");
						inpt.append(opt);
						if(value != null)
						  inpt.val(value.toUpperCase());
    			}
					
					//if(noDisplay)
					//  inpt.noDisplay = noDisplay;
					
					return inpt;
			}
			
    } catch(err){ Log.Add("PropertiesEditor.GetComplexInput", err, LogType.Error); }	
	}
	
	
	
  function SaveProperties(properties, _table)
  {
    try{
		
        for(var i = 0; i < properties.length; i++)
        {
          
          var value = null;
					
					var _id = "#propertyeditor" + properties[i].Item.ID;
          
          switch(properties[i].Item.Type)
          {
            case "text":
							value = _table.find(_id ).val();
              break;
            
            case "checkbox":
              value = _table.find(_id )[0].checked;
              break;
            
            case "select":
              value = _table.find(_id).val();
              break;
							
						case "complex":
						  value = SaveComplexInput(properties[i]);
						  break;
							
						case "memo":
						  value = _table.find(_id).val();
							break;
          }
          
					//alert(properties[i].Set + "\n\n" + value)
          if(properties[i].Set != null)
            properties[i].Set(value);
						
        }


    } catch(err){ Log.Add("PropertiesEditor.SaveProperties", err, LogType.Error); }
  }
	
	
	function SaveComplexInput(property)
	{
	  try{
		
    		var params = property.Get();
    
    		for(var i = 0; i<params.length; i++) // loops through each parameter in an array of parameters such as several params in a select
    		{
    			var param = params[i];
    
    			jQuery.each(param, function(field, value){ // loops through each field in a complex property such as name, type, value for a select param
					  _complexPropertyIndex++;
    				var inpt = _div.find(".PropertyEditorTable").find("#" + _complexPropertyIndex); 
						var value = inpt.val();
						param[field] = value;
    			});
    		}	
				
				return params;	  
					  
    } catch(err){ Log.Add("PropertiesEditor.SaveComplexInput", err, LogType.Error); }	
	}
	
 	
}













PropertyFields = new function()
{
  var items = null;

  return{
    GetProperty: function(strItem)
    {
		  try{
        if(items == null)
          LoadItems();
      
        for(var i = 0; i<items.length; i++)
        {
          if(items[i].Item == strItem)
            return items[i];
        }

        Log.Add("PropertyFields.GetProperty", "A property item could not be found for " + strItem, LogType.Warning);
      
      } catch(err){ Log.Add("PropertyFields.GetProperty", err, LogType.Error); }
    }
  }
  
  function LoadItems()
  {
	  try{
      items = new Array();
  
      // Template Editor Items
      AddItem("Borderless", "Borderless", "Whether the control shows a border", "checkbox");
      AddItem("Caption", "Caption", "The caption of the component", "text");
      AddItem("Checked", "Checked", "Whether or not the component is checked", "text");
      AddItem("Class", "Class", "The css class of the component", "select");
      AddItem("Condition", "Condition", "The condition that determines if stingray will return the component", "text");
      AddItem("DefaultButton", "DefaultButton", "If set to 'true' the click event for the button will be executed when the user hits enter while on any element in the parent Static Container", "text");			
      AddItem("EditHTML", "EditHTML", "Replaces the text area with an html editor", "text");
      AddItem("EditorTextFilters", "Filters", "Filters | Filter [select:,CustomExpression,Date,Email,Equal,Float,GreaterThan,GreaterThanEquals,Integer,LessThan,LessThanEquals,Phone,SSN,State,Time,ZipCode] | Data Type [select:,DATE,FLOAT,INTEGER,STRING] | Parameter", "complex");
      AddItem("Height", "Height", "The height of the component", "text");
      AddItem("ID", "ID", "The ID of the component", "text");
      AddItem("Left", "Left", "The left position of the component", "text");
      AddItem("MaxLength", "MaxLength", "The maximum number of characters allowed", "text");
      AddItem("MultiSelect", "MultiSelect", "Allow multiple items to be selected", "checkbox");
      AddItem("Name", "Name", "The name of the component", "text");
      AddItem("OnClick", "OnClick", "The javascript that executes when the component is clicked", "text");
      AddItem("Options", "Options", "The variable that fills the dropdown options", "text");
      AddItem("Required", "Required", "If the component requires input", "text");
      AddItem("Scripts", "Scripts", "Javascript functions that will be made available on this page", "memo");
      AddItem("ScriptFunctions", "ScriptFunctions", "User functions | Events [select: " + new TemplateBase().GetEventList() + "] | User functions", "complex");			
      AddItem("Size", "Size", "The size attribute of an input", "text");
      AddItem("Style", "Style", "The style applied to the component", "text");
      AddItem("TabIndex", "TabIndex", "The tab index of the component", "text");
      AddItem("Tags", "Tags", "Attributes without value (eg. disabled, readonly, checked...) added to the input element", "text");
      AddItem("Target", "Target", "The link target", "text");
      AddItem("Top", "Top", "The top position of the component", "text");
      AddItem("Tooltip", "Tooltip", "The tooltip that displays above a component", "text");			
      AddItem("Type", "Type", "The type of button", "select");
      AddItem("Validate", "Validate", "If the button should validated the page", "checkbox");
      AddItem("Value", "Value", "The value of the component", "text");
      AddItem("ValueLessAttrs", "ValueLessAttrs", "The attributes ", "text");
      AddItem("Width", "Width", "The width of the component", "text");
			
			// Ajax Postable Items
      AddItem("EventVRM", "EventVRM", "The VRM [with params] to be called by Ajax", "text");
      AddItem("Event", "Event", "The event that fires the ajax post", "select");
      AddItem("AjaxEnabled", "AjaxEnabled", "Whether the ajax post feature is enabled", "checkbox");		
  
  		//Rule Editor Items
      AddItem("Comment", "Comment", "Component comments that show on hover. The first line (up to 50 characters) display next to the component ", "text");			
      AddItem("Condition", "Condition", "The Condition in an if statement", "text");
      AddItem("CompiledScript", "CompiledScript", "Compiled Script | Function [select:,Replace]| Param|Param|Param|Param", "complex");
      AddItem("DELPHI", "DELPHI", "Delphi code", "memo");
      AddItem("ErrorMessage", "ErrorMessage", "The error message that will be displayed to the user", "memo");
      AddItem("ID", "ID", "The ID of the component", "text");
      AddItem("J1", "J1", "The Component that is called by default", "text");
      AddItem("J2", "J2", "The Component that is called on a false condition", "text");
      AddItem("MathParams", "MathParams", "Math Properties | Name | Format [select:INTEGER,LONGDATETIME,LONGDATETIMEAMPM,SHORTDATE,ROUND,FLOAT] | Value", "complex");
      AddItem("Query", "Query", "A SQL query", "memo");
      AddItem("QueryParams", "QueryParams", "Query Parameters | The param name | The data type [select:BOOLEAN,CURRENCY,DATETIME,FLOAT,INTEGER,STRING] | The param value", "complex");
      AddItem("RuleName", "RuleName", "The vrm to be called", "text");
      AddItem("SetParams", "SetParams", "Set Properties | The property name | The property value", "complex");
      AddItem("Target", "Target", "The stingray target div that will receive the rendered template html", "text");
      AddItem("X", "X", "The left coordinate of the component", "text");
      AddItem("Y", "Y", "The top coordinate of the component", "text");
  	} catch(err){ Log.Add("PropertyFields.LoadItems", err, LogType.Error); }	
  }
  
  
  function AddItem(Item, Caption, Description, Type)
  {
	  try{
      var item = new PropertyItem(Item, Caption, Description, Type);
    
      items[items.length] = item;
		} catch(err){ Log.Add("PropertyFields.AddItem", err, LogType.Error); }
  }
 
 
  
  function PropertyItem(strItem, Caption, Description, Type)
  {
	  try{
      this.Item = strItem;
      this.ID = strItem;
      this.Caption = Caption;
      this.Description = Description;
      this.Type = Type;
    } catch(err){ Log.Add("PropertyFields.PropertyItem", err, LogType.Error); }
  }
}
