//  ScriptingContainer [NT 01/15/2008]
function ScriptingContainer()
{
  try{
	
  this.inheritFrom = TemplateBase;

	this.inheritFrom();			

  /* PRIVATE PROPERTIES */
  var control = null;
  
  var h3 = null;
	
	var script = null;

  var featuresAdded = false;
  
  var properties = null;
  


  /* PUBLIC METHODS */

    // Appends the control to a container element
    this.AppendTo = function(ContainerElement)
    {
        try{
        
          $(ContainerElement).append(control);
					
					this.BaseLoad(control);
          
          if(Editor.IsEnabled())
            this.EditMode();
            
        } catch(err){ Log.Add("ScriptingContainer.AppendTo", err, LogType.Error);}
    };
    
    this.Create = function()
    {
      try{
        
          control = $("<div condition='' class='component ScriptingContainer' ref='ScriptingContainer'><h3 class='handle'>Javascript Functions</h3><pre>function OnLoad(){scroll(0,0);}</pre></div>");
          
          h3 = $(control.find(">h3"));
					
					script = $(control.find(">pre"));
          
      } catch(err){ Log.Add("ScriptingContainer.Create", err, LogType.Error);}

    };
    
    this.DefaultMode = function()
    {
      try{
			
				$(control).css("display", "none");		
			
        RemoveFeatures();
			
			  var str = control.text();
			
    		var fns = GetFunctions(str);
    
    		CustomScript.Reset();
				
				var loadScripts = true;
    		
    		for(var i = 0; i<fns.length; i++)
    		{
    		  var fn = fns[i];
					
					try{
    			
    			  CustomScript[fn.Name] = new Function(fn.Params, fn.Body);

				  }catch(err){
					  loadScripts = false;
						alert("Error binding custom function '" + fn.Name + "': " + err.message);
					  Log.Add("ScriptingContainer.DefaultMode", "Error binding custom function '" + fn.Name + "': " + err.message, LogType.Warning);
					}
    		}
				
				if(loadScripts){
  				if(CustomScript.OnLoad)
  				{
  				  if(!PropertiesEditor.Saving)
    				  setTimeout("CustomScript.OnLoad()", 100); // give it 1/10 of a second to finish loading all the html components
  				}
				}
				      
        Helper.RemoveComponentID(control);
        
      } catch(err){ Log.Add("ScriptingContainer.DefaultMode", err, LogType.Error);}
    };


    this.EditMode = function()
    {
      try{
      
        AddFeatures();
        
      } catch(err){ Log.Add("ScriptingContainer.EditMode", err, LogType.Error);}
    };


    this.GetProperties = function()
    {
       try{

          var properties = this.GetBaseProperties();
          
          properties[properties.length] = new PropertiesEditor.Property(PropertyFields.GetProperty("ID"), this.GetID, this.SetID);
       
          properties[properties.length] = new PropertiesEditor.Property(PropertyFields.GetProperty("Scripts"), this.GetScripts, this.SetScripts);
          
          return properties;
          
       } catch(err){ Log.Add("ScriptingContainer.GetProperties", err, LogType.Error);}
    };
    

    this.Load = function(ControlElement)
    {
       try{
       
          control = $(ControlElement);
					
					this.BaseLoad(control);
          
          h3 = $(control.find(">h3"));
					
					script = $(control.find(">div"));
					
					// TODO: remove when finished converting to pre tags
					if(script.length == 0)
					  script = $(control.find(">pre"));
					// end remove
					
				  script.css("display", "none");					
					
					var js = script.text();
					
					script.text(js);
					
       } catch(err){ Log.Add("ScriptingContainer.Load", err, LogType.Error);}
    };
		
		this.Show = function(table)
		{
		  control.css("display", "block");	
			control.html(table);	
		}
		
		this.Hide = function()
		{
		  control.html("");
		  control.css("display", "none");
		}

    this.GetControl = function(){ try{ return control; } catch(err){ Log.Add("ScriptingContainer.GetControl", err, LogType.Error);} };

    this.GetID = function(){try{  return  control.attr("id"); } catch(err){ Log.Add("ScriptingContainer.GetID", err, LogType.Error); }};

    this.GetScripts = function(){try{ return script.text() } catch(err){ Log.Add("ScriptingContainer.GetScripts", err, LogType.Error);}};
    
    this.SetID = function(newID){try{ control.attr("id", newID);} catch(err){ Log.Add("ScriptingContainer.SetID", err, LogType.Error); }};
    
    this.SetScripts = function(newScripts)
		{ 
		  try{ 
			
			  var ret = AttachScript(newScripts);
				
				if(ret == null)
				{
			
 					// TODO: remove when finished converting to pre tags
					if(script[0].tagName == "DIV")
					{
					  script.remove();

  				  script = $("<pre/>");
						
						control.append(script);
						
						alert("The scripting container has been updated, please save the template");
					}
					// end remove
				  
			    script.text(newScripts);
				}
				else
				  alert("Function " + ret[0].Name + " threw an error:\n\n" + ret[1].message);
					
				CustomScript.Reset();
				
				
			
			} catch(err){ Log.Add("ScriptingContainer.SetScripts", err, LogType.Error);}
		}

    
    /* PUBLIC PROPERTIES */    
    this.NameRequired = false;
    
    this.Ref = "ScriptingContainer";
    


  



  /* PRIVATE METHODS */

  // adds features to the control based on the rules specified for this type of control
  function AddFeatures()
  {
     try{
     
        if(featuresAdded)
          return;
					
				h3.toggle(
				  function(){
					  script.css("display", "block");
					},
				  function(){
					  script.css("display", "none");					
					}					
				);
        
        $(control).sortable({ items: '> .component' });
				
				$(control).css("display", "block");
         
        control.bind("dblclick.ScriptingContainer", function(event){event.stopPropagation(); Editor.ShowProperties(control); });
        
        h3.attr("unselectable", "on");
				
        featuresAdded = true;
        
     } catch(err){ Log.Add("ScriptingContainer.AddFeatures", err, LogType.Error);}
        
  }
  
  // removes features from the control that were previously added 
  function RemoveFeatures()
  {
     try{ 
       
        if(!featuresAdded)
          return;
        
        control.unbind("dblclick.ScriptingContainer");
        
        $(control).sortable("disable");
				
        h3.removeAttr("unselectable");
          
        featuresAdded = false;
        
     } catch(err){ Log.Add("ScriptingContainer.RemoveFeatures", err, LogType.Error);}
  }
	
	function GetFunctions(str)
	{
	  try{
		
		  var arr = new Array();

  		var fns = str.split("function ");
			
			if(fns == null)
			  return arr;
  		
  		for(var i = 1; i<fns.length; i++)
  		{
  		  var fn = fns[i];
  			
    		var _name = fn.substring(0, fn.indexOf("{"));
  			
  			exp = /\([^\)]+\)/g;
  					
  			var params = _name.match(exp);
  			
  			if(params == null || params.length == 0)
  			  params = "";
  			else
  			  params = params[0];
  			
  			params = params.replace("(", "").replace(")", "");
  			
  			if(_name.indexOf("(")>-1)
  			  _name = _name.substring(0, _name.indexOf("("));
    		
    		var body = fn.substring(fn.indexOf("{")+1);
  			
        body = body.substring(0, body.lastIndexOf("}"));
  			
  			var funct = new Script(_name, params, body);
				
				//alert("'" + _name + "'\n\n'" + params + "'\n\n'" + body + "'");
  			
  			arr.push(funct);
  		}
  		
  		return arr;
			
     } catch(err){ Log.Add("ScriptingContainer.GetFunctions", err, LogType.Error);}	  
	}

	function AttachScript(strScript)
	{
	  try{

    		var fns = GetFunctions(strScript);	
    
    		CustomScript.Reset();
				
				var currentFunction = null;
    		
    		for(var i = 0; i<fns.length; i++)
    		{
    		  var fn = fns[i];
					
					currentFunction = fn;
    			
    			CustomScript[fn.Name] = new Function(fn.Params, fn.Body);
    		}
				
				return null;	  
				
		} catch(err){return [currentFunction, err]; }	
	
	}


  } catch(err){ Log.Add("ScriptingContainer", err, LogType.Error); }
}




CustomScript = new function()
{
  try{
  	
    // clear the previously added functions
    this.Reset = function()
    {
      jQuery.each(
          CustomScript, 
          function(field, value){
    		  if(field != "Reset")
    			{
    			  CustomScript[field] = null;					
    			}
    	  }
    	);
    }
	}catch(err){Log.Add("ScriptingContainer.CustomScript", err, LogType.Error);}
}

function Script(name, params, body)
{
  try{
    this.Name = name;
    this.Params = params;
    this.Body = body;
	}catch(err){Log.Add("ScriptingContainer.Script", err, LogType.Error);}		
}

