//Snapsis CSSEditor functions
//Copyright John Mitchell - Snapsis Software, Inc. http://www.snapsis.com
//    Parts of this script derived from:
//    http://home.att.net/~m.synovic/codespy/codespy.html

var snapsis_CSSRulesList = new Hashtable();
var snapsis_CursorSave;
var snapsis_CSSViewerActive = false;
var snapsis_CSSViewerFrozen = true;
var snapsis_MoveObject = null;
var snapsis_MoveOffsetX = 0;
var snapsis_MoveOffsetY = 0;

var snapsis_diffX = snapsis_diffY = 0;
var snapsis_xScroll = snapsis_yScroll = 0;
var snapsis_DockableContainerList = new Array('CSSEditorContainer');
var snapsis_AutoScrollContainersInterval = window.setInterval('snapsis_AutoScrollContainers()',1);
var snapsis_SlideContainers = new Hashtable();
function snapsis_SlideContainer(){
    this.id = new String();
    this.interval = 0;
    this.left = 0;
    this.top = 0;
}             
function snapsis_onLoadAdmin()
{
    //just because the onLoad event has fired it doesn't mean that all 
    //of the elements are ready, so wait for the Document to be ready
    setTimeout("snapsis_DocumentComplete()",10);
}
function snapsis_DocumentComplete()
{
    if(document.readyState == "complete")
    {
        //pop them up off screen, then move them over to dock position with the slider
        snapsis_popUp('CSSEditorContainer',-700,100);
        snapsis_dockAllContainers();
        
    }
    else
    {
        //keep coming back to see when it's done
        setTimeout("snapsis_DocumentComplete()",10);
    }
}
function snapsis_dockAllContainers()
{    
		for ( var i in snapsis_DockableContainerList )
		{
		  snapsis_dockContainer(snapsis_DockableContainerList[i]);
		}
}
function snapsis_dockContainer(containerId)
{   var ctr = document.getElementById(containerId);
    if(ctr != null)
    {
        var tabImage = document.getElementById(containerId +"Tab");
        if (tabImage)
            tabImage.width=20;
        var oSlideContainer = new snapsis_SlideContainer();
        oSlideContainer.id = containerId;
        oSlideContainer.interval = setInterval("snapsis_slideContainerLeft('" + containerId + "',50)",5);
        oSlideContainer.left = ctr.style.left;
        snapsis_SlideContainers.add(containerId,oSlideContainer);
    }
}
function snapsis_undockContainer(containerId)
{
    var ctr = document.getElementById(containerId);
    var tabImage = document.getElementById(containerId +"Tab");
    if (tabImage)
        tabImage.width=0;
    var oSlideContainer = new snapsis_SlideContainer();
    oSlideContainer.id = containerId;
    oSlideContainer.interval = setInterval("snapsis_slideContainerRight('" + containerId + "',50)",5);
    oSlideContainer.left = ctr.style.left;
    snapsis_SlideContainers.add(containerId,oSlideContainer);
}
function snapsis_slideContainerRight(containerId,step)
{
    if (step == null)
        step=50;
    var oSlideContainer = snapsis_SlideContainers.get(containerId)
    var ctr = document.getElementById(containerId);
    if (ctr.style.left < 0)
	{
	    ctr.style.left=ctr.style.left + 50 ;
    }
    else
    {
        ctr.style.left=0;
        clearInterval(oSlideContainer.interval);
        snapsis_SlideContainers.remove(containerId);
    }
}

function snapsis_slideContainerLeft(containerId,step)
{
    if (step == null)
        step=50;
    var oSlideContainer = snapsis_SlideContainers.get(containerId)
    var ctr = document.getElementById(containerId);
    var dockPos = (0 - ctr.offsetWidth) + 23;
    if (ctr.style.left > dockPos)
    {
	    ctr.style.left=ctr.style.left - 50 ;
    }
    else
    {
        ctr.style.left=dockPos;
        clearInterval(oSlideContainer.interval);
        snapsis_SlideContainers.remove(containerId);
    }
}

function snapsis_AutoScrollContainers() {
    if (document.body)
    {
        snapsis_diffX = document.body.scrollLeft;
	    snapsis_diffY = document.body.scrollTop; 
	}
		
	if(snapsis_diffY != snapsis_yScroll) {
        percent = .1 * (snapsis_diffY - snapsis_yScroll);
        if(percent > 0){
            percent = Math.ceil(percent);
        } else {
            percent = Math.floor(percent);
        }
		for ( var i in snapsis_DockableContainerList )
		{
            var ScrollObject = document.getElementById(snapsis_DockableContainerList[i]);
            if (ScrollObject) 
            {
                if (ScrollObject.style.display == "block" )
		            ScrollObject.style.pixelTop += percent;
		    }
		}
        snapsis_yScroll = snapsis_yScroll + percent;
    }
	if(snapsis_diffX != snapsis_xScroll) {
		percent = .1 * (snapsis_diffX - snapsis_xScroll);
		if(percent > 0){
		    percent = Math.ceil(percent);
        } else {
            percent = Math.floor(percent);
        }
		for ( var i in snapsis_DockableContainerList )
		{
            var ScrollObject = document.getElementById(snapsis_DockableContainerList[i]);
            if (ScrollObject) 
            {
                if (ScrollObject.style.display == "block" )
	    	        ScrollObject.style.pixelLeft += percent;
	    	}
		}
		snapsis_xScroll = snapsis_xScroll + percent;
	}
}
function snapsis_popUp(oContainerId,leftPos, topPos){
   	var oContainer = document.getElementById(oContainerId);
    if (oContainer != null )
    {
		if (oContainer.style.zIndex < snapsis_zIndexTop )
		        oContainer.style.zIndex=snapsis_zIndexTop++;

		if (leftPos != null)
			oContainer.style.left=leftPos;
	    else
	        oContainer.style.left=event.clientX+10;
		if (topPos != null)
			oContainer.style.top=topPos;
    	else
	        oContainer.style.top=event.clientY+10;
	    
		var oMoveHandle = document.getElementById(oContainer.id + "Handle");
	    if ( oMoveHandle )
		   oMoveHandle.attachEvent("onmousedown",snapsis_startMouseMove);

		oContainer.style.display="block";
		oContainer.style.visibility="visible";
		snapsis_CurrentContainerId = oContainer.id;
	}
}
function snapsis_hidePopUp(oContainerId){
    if (oContainerId)
        snapsis_CurrentContainerId = oContainerId;
	if (snapsis_CurrentContainerId != null){
		var oContainer=document.getElementById(snapsis_CurrentContainerId);
		if (oContainer != null){
			oContainer.style.display="none";
			oContainer.style.visibility="hidden";
			var oMoveHandle = document.getElementById(oContainer.id + "Handle");
			if ( oMoveHandle )
			{
			    oMoveHandle.detachEvent("onmousedown",snapsis_startMouseMove);
			    oMoveHandle.detachEvent("onmouseup",snapsis_cancelMouseMove);
			}
		}
	}
	return;
}

function snapsis_ToggleDisplay(oContainerId,onoff){

		var oContainer=document.getElementById(oContainerId);
		if (oContainer != null)
		{
		    
		    if (onoff)
		    {
    		    if ( oContainer.style.display == "block" || onoff.toLowerCase() == 'off')
    		    {
    		       oContainer.style.display = "none";
    		       oContainer.style.visibility = "hidden";
                }
                else
                {
                   oContainer.style.display = "block";
                   oContainer.style.visibility = "visible";
                }
            }
            else
            {
    		    if ( oContainer.style.display == "block")
    		    {
    		       oContainer.style.display = "none";
    		       oContainer.style.visibility = "hidden";
                }
                else
                {
                   oContainer.style.display = "block";
                   oContainer.style.visibility = "visible";
                }
            }                
		}
	return;
}

//the Reload function get's called when the stylesheet is updated 
//on the server so that the changes can be reflected back on the client
//it is equivalent to holding CTRL and refreshing the browser
function snapsis_Reload(removePost)
{
    if (removePost)
    {
        //this line removes the last post so that the reload won't prompt for re-submit
        if (location.href.indexOf("?") == -1)
            location.href=location.href + '?CSSEditorAction=RELOAD';
        else
            location.href=location.href + '&CSSEditorAction=RELOAD';
    }
    else
    {
        location.reload(true);
    }
}
function snapsis_SaveStylesheet()
{
    if (document.getElementById("CSSStylesheetTextarea").value == "")
        document.getElementById("CSSStylesheetText").value=snapsis_getStylesheetText();
    else
        document.getElementById("CSSStylesheetText").value=document.getElementById("CSSStylesheetTextarea").value;
    snapsis_SubmitForm("SAVE");
}    
function snapsis_getStylesheetText()
{
    var StylesheetText = "/* Snapsis CSS Editor Combined Stylesheets \r\n"
                        + "      This stylesheet is located at: \r\n        " + snapsis_SkinPath + "*/\r\n ";
    var cssRulesList = snapsis_CSSRulesList.values();
    var cssRule = new snapsis_CSSRule();
    for ( var i in cssRulesList )
    {
        cssRule = cssRulesList[i];
        if (cssRule)
        {
            StylesheetText += cssRule.selectorText + "\r\n";
            StylesheetText += snapsis_getCSSRuleProperties(cssRule.selectorText.toLowerCase()) + "\r\n";
        }
    }
    return StylesheetText;
}
function snapsis_SubmitForm(ServerAction)
{
    document.getElementById("CSSEditorAction").value=ServerAction;
    document.forms[0].submit();
    return true;
}    
function snapsis_toggleCSSViewer(imageClicked)
{
    event.srcElement.style.cursor = snapsis_CursorSave;
    if ( snapsis_CSSViewerActive || imageClicked )
    {

        if (snapsis_CSSViewerFrozen)
            snapsis_CSSViewerFrozen = false; 
        else
            snapsis_CSSViewerFrozen = true; 


        if ( snapsis_CSSViewerActive && imageClicked)
        {
                snapsis_CSSViewerActive = false;
                snapsis_CSSViewerFrozen = true;
        }
        else if( imageClicked )
        {
            snapsis_CSSViewerActive = true;
            snapsis_CSSViewerFrozen = false;
        }

        if( snapsis_CSSViewerFrozen )
        {
            document.getElementById("body").style.cursor = "";
            document.detachEvent("onmouseover",snapsis_CSSViewerMouseOver);
            document.detachEvent("onmouseout",snapsis_CSSViewerMouseOut);
            document.detachEvent("onclick",snapsis_CSSViewerClick);
            document.detachEvent("oncontextmenu",snapsis_CSSViewerClick);
        }
        else
        {
            document.attachEvent("onmouseover",snapsis_CSSViewerMouseOver);
            document.attachEvent("onmouseout",snapsis_CSSViewerMouseOut);
            document.attachEvent("onclick",snapsis_CSSViewerClick);
            document.attachEvent("oncontextmenu",snapsis_CSSViewerClick);
            document.getElementById("body").style.cursor = "DesktopModules/SnapsisDNN/CSSEditor/images/css.cur";
        }
    
    }
    event.returnValue = false;
    event.cancelBubble = true;
    return false;
}
function snapsis_CSSViewerMouseOver()
{
    var mo_Element = event.srcElement;
    var RuleProperties = "";
    mo_Element.style.cursor = "DesktopModules/SnapsisDNN/CSSEditor/images/css.cur";
    
    //uncomment this if you don't want to see the CSS Editor's styles with the magic wand
//    if (mo_Element.id.substring(0,3).toUpperCase() != "CSS")
//    {
        var SVText = "";
        if( mo_Element.id !="" )
        {
            //SVText += "<b>ID:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b>" + mo_Element.id + "<br>";
            if ( mo_Element.className =="" )
            {
                document.getElementById('CSSRuleSelector').value= "#" + mo_Element.id;
                document.getElementById('CSSRuleProperties').value=snapsis_getCSSRuleProperties("#" + mo_Element.id.toLowerCase());
            }
        }
        if ( mo_Element.className !="" )
        {
            //SVText += "<b>Class:&nbsp;&nbsp;</b>" + mo_Element.className + "<br>";
            document.getElementById('CSSRuleSelector').value= "." + mo_Element.className;
            document.getElementById('CSSRuleProperties').value = 
                    snapsis_getCSSRuleProperties("." + mo_Element.className.toLowerCase());
                
        }
        //var cssText = mo_Element.style.cssText;
        //cssText = cssText.replace(/CURSOR: url\('DesktopModules\/SnapsisDNN\/CSSEditor\/images\/css.cur'\)/gi,'');
        //cssText = cssText.replace(/; ;/gi,';');
        //if ( cssText !="")
        //      SVText += "<b>InLine:&nbsp;&nbsp;</b>" + cssText.replace(/;/gi,';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
        //if ( SVText != "")
            //document.getElementById("CSSViewerContainer").innerHTML = SVText ;
//    }
    event.returnValue = false;
    event.cancelBubble = true;
    return false;
}
function snapsis_CSSRulePropertiesSelectLine()
{
    //select the line that the cursor is on
    var RulesList = document.getElementById("CSSRuleProperties");
    var rng = document.selection.createRange();           // create a range for the cursor position
    var c = "";
    var i = 0; //failsafe
    rng.moveStart("character",1);  //move up one character in case the cursor is currently at the beginning
    while( c != "{")  //don't go past the start
    {
        rng.moveStart("character",-1);  //move the start of the range back until a semi-colon is found
        c = rng.text.charAt(0);
        ++i;
        if ( i > 256)//don't look any farther than 256 characters
            break;
        if ( c == ';' )
            break;
    }
    i = 0;
    rng.moveStart("character",2); //move ahead off the semi-colon or the start brace
    while( c != "}")  //don't go past the end
    {
        rng.moveEnd("character",1);
        c = rng.text.charAt(rng.text.length-1); //move the end of the range forward until a semi-colon is found
        if ( c == ';' || c == '' )
            break;
        ++i;
        if ( i > 256)//don't look any farther than 256 characters
            break;
    }
    if ( i < 256)
    {
        if ( c == '}' )
            rng.moveEnd("character",-2);
        if (rng.text != '')
            rng.select();
    }
        
}
function snapsis_CSSViewerMouseOut()
{
    var mo_Element = event.srcElement;
    mo_Element.style.cursor = snapsis_CursorSave;
    document.getElementById('CSSRuleSelector').value= "";
    document.getElementById('CSSRuleProperties').value = "";
    event.returnValue = false;
    event.cancelBubble = true;
    return false;
}
function snapsis_CSSViewerClick()
{
    var mo_Element = event.srcElement;
    mo_Element.style.cursor = snapsis_CursorSave;
    var mo_Element = event.srcElement;
    if ( mo_Element.className !="" || mo_Element.id !="")
        snapsis_toggleCSSViewer();
        
    event.returnValue = false;
    event.cancelBubble = true;
    return false;
}
function snapsis_EditStylesheet()
{
    //hide the Toolbar
    snapsis_CSSToggleDisplay('CSSToolbarContainer','off');
    //hide the Rule Selector
    snapsis_CSSToggleDisplay('CSSRuleSelectorContainer','off');
    //hide the RuleProperties
    snapsis_CSSToggleDisplay('CSSRuleProperties','off');
    //hide List Container
    snapsis_CSSToggleDisplay('CSSRulesListContainer','off');  
    
    var CSSStylesheetTextarea = document.getElementById("CSSStylesheetTextarea");
    if ( CSSStylesheetTextarea != null )
    {
        //put the Rules into the textarea
        CSSStylesheetTextarea.value = snapsis_getStylesheetText();
        //show the Textarea and expand the size of the editor
        snapsis_CSSToggleDisplay('CSSStylesheetTextareaContainer','on',120);
    }
    snapsis_ToolbarButtonPressed = "";
    
}
function snapsis_CancelEdit()
{
     //hide the Toolbar
    snapsis_CSSToggleDisplay('CSSToolbarContainer','on');
    //hide the Rule Selector
    snapsis_CSSToggleDisplay('CSSRuleSelectorContainer','on');
    //hide the RuleProperties
    snapsis_CSSToggleDisplay('CSSRuleProperties','on');   
    var CSSStylesheetTextarea = document.getElementById("CSSStylesheetTextarea");
    if ( CSSStylesheetTextarea != null )
    {
        //put the Rules into the textarea
        CSSStylesheetTextarea.value = "";
        //hide the Textarea and decrease the size of the editor
        snapsis_CSSToggleDisplay('CSSStylesheetTextareaContainer','off',-120);
    }  
}
function snapsis_CSSHelp()
{
    window.open('DesktopModules/SnapsisDNN/CSSEditor/CSSEditorHelp.html','Help','width=500,height=400,resizable=yes,toolbars=no,scrollbars=yes,location=false');
}
function snapsis_CreateCSSRule()
{
    //creates a CSS Rule from the Text entered in the editor
   var cssRule = new snapsis_CSSRule();
    cssRule.selectorText = document.getElementById("CSSRuleSelector").value;
    cssRule.Path = snapsis_SkinPath;
    var cssText = document.getElementById("CSSRuleProperties").value;
    //trim off the starting and closing brace if it's there
    if (cssText.substring(0,1) == "{")
       cssText = cssText.substring(1,cssText.length -1);
    if (cssText.substring(cssText.length-1,1) == "}")
       cssText = cssText.substring(0,cssText.length -1);
    cssRule.cssText = cssText;
    cssRule.combined = true;   
    return cssRule; 
}
function snapsis_CSSRule()
{
    this.selectorText = new String();
    this.combined = false;
    this.Path = new String();
    this.cssText = new String();
    this.properties = new Hashtable();
}               
function snapsis_CSSRuleProperty()
{
    this.name = new String();
    this.value = new String();
}               
function snapsis_CreateRulesList(hideInlineRules)
{
    var RulesListContainer = document.getElementById('CSSRulesListContainer');
    var html = "<input type=\"hidden\" id=\"selectedRule\" name=\"selectedRule\" value=\"\">";
    html += "<table cellpadding=\"3\" cellspacing=\"0\" border=\"0\" style=\"position:relative;width:100%;height:100%;background-color:white;\">";
    
    //loop through all the rules in the documents stylesheet and add them to the list
    //rules will be added  in order and over-ridding (Cascaded rules) will be merged to reflect 
    //the combined styles 
    for (var i = 0; i < document.styleSheets.length; i++) 
    {
        var show = true;
        if ( !( hideInlineRules && !document.styleSheets(i).href ))
        {
            for (var j = 0; j < document.styleSheets(i).rules.length; j++)
            {
                var cssRule = new snapsis_CSSRule();
	            cssRule.selectorText = document.styleSheets(i).rules(j).selectorText;
	            var selectorTextKey = cssRule.selectorText.toLowerCase();
	            cssRule.Path = document.styleSheets(i).href
	            cssRule.Path = cssRule.Path.substring(0,cssRule.Path.lastIndexOf("/")+1);
	            cssRule.cssText = document.styleSheets(i).rules(j).style.cssText;
                if ( ! snapsis_CSSRulesList.containsKey(selectorTextKey) )
                {
                    html += snapsis_NewRulesListRowHTML(cssRule); 
                }
                snapsis_UpdateCSSRulesList(cssRule);
	        }
	    }
    }     
    html += "<NewRule><tr><td height=\"100%\">&nbsp;</td></tr></table>";    
    RulesListContainer.innerHTML = html;

}
function snapsis_NewRulesListRowHTML(cssRule)
{
    var selectorTextKey = cssRule.selectorText.toLowerCase();
    var html= "<tr><td id=\"cssrule_" + selectorTextKey + "\" nowrap class=\"CSSListSelect\""
                     + " onmouseover=\"this.className='CSSListSelect_MO'\"" 
                     + "';this.title=snapsis_getCSSRuleProperties('" 
                     + selectorTextKey + "');\" onmouseout=\"this.className='CSSListSelect'\"" 
                     + " onclick=\"snapsis_CSSToggleDisplay('CSSRulesListContainer');"
                     + " document.getElementById('CSSRuleProperties').value=snapsis_getCSSRuleProperties('" 
                     + selectorTextKey + "');document.getElementById('CSSRuleSelector').value='" + cssRule.selectorText + "'\" >" 
                     + cssRule.selectorText + "</td></tr>"   
    return html;
}
function snapsis_AddRulesListRow(cssRule)
{
   var NewRulesListRowHTML = snapsis_NewRulesListRowHTML(cssRule);
   var RulesListContainer = document.getElementById('CSSRulesListContainer'); 
   var html = RulesListContainer.innerHTML;
   html = html.replace(/<NewRule>/gi,NewRulesListRowHTML + '<NewRule>');
   RulesListContainer.innerHTML = html;
}
function snapsis_AddNewRule()
{
    snapsis_CSSToggleDisplay('CSSRulesListContainer','off');  
    document.getElementById('CSSRuleSelector').focus();
    document.getElementById('CSSRuleSelector').value="New Rule";
    document.getElementById('CSSRuleSelector').select();
    document.getElementById('CSSRuleProperties').value =""; 
}
function snapsis_RemoveRulesListRow(selectorTextKey)
{
   var RulesListContainer = document.getElementById('CSSRulesListContainer'); 
   var html = new String(RulesListContainer.innerHTML);
   var RowStart = html.indexOf('cssrule_' + selectorTextKey ); 
   if (RowStart != -1)
   {
        var RowEnd = html.indexOf('</TD></TR>',RowStart) + 10;
        RowStart = RowStart - 33;  // move to start of Row
        RulesListContainer.innerHTML = html.substring(0,RowStart) + html.substring(RowEnd,html.length);
   }
}
function snapsis_RemoveRule()
{
    var selectorTextKey = document.getElementById('CSSRuleSelector').value.toLowerCase();
    snapsis_CSSRulesList.remove(selectorTextKey);
    document.getElementById('CSSRuleSelector').value = "";
    document.getElementById('CSSRuleProperties').value = ""; 
    snapsis_RemoveRulesListRow(selectorTextKey);
}
function snapsis_CSSRulePropertiesChange()
{
    var selectorTextKey = document.getElementById('CSSRuleSelector').value.toLowerCase();
    if (selectorTextKey != "" && selectorTextKey != "css rule selector..")
    {
         //Update the rulesList with the changed rule
        var cssRule = snapsis_CreateCSSRule();
        //if it's a new rule then add it to the drop-down list
        if ( ! snapsis_CSSRulesList.containsKey(selectorTextKey) )
        {
            snapsis_AddRulesListRow(cssRule);
        }
        snapsis_UpdateCSSRulesList(cssRule);
    }
}
function snapsis_CSSRuleSelector_Blur()
{
   snapsis_CSSToggleDisplay('CSSRulesListContainer','off');  
   document.getElementById('CSSRuleProperties').value = 
        snapsis_getCSSRuleProperties(document.getElementById('CSSRuleSelector').value.toLowerCase()); 
}
function snapsis_UpdateCSSRulesList(cssRule)
{
   var ruleValue = '';
   var Properties = new Hashtable();
   // an object to hold a single Name/Value pair for a property of a rule
   var ruleProperty ;
   var selectorTextKey = cssRule.selectorText.toLowerCase();
   if ( snapsis_CSSRulesList.containsKey(selectorTextKey) )
   {
       //if it's already been added, then remove it and merge the properties
       //with the properties from the rule that is overriding it
       //only get the properties from the rule if it hasn't been combined yet
       if (!cssRule.combined)
            Properties = snapsis_CSSRulesList.get(selectorTextKey).properties;
       snapsis_CSSRulesList.remove(selectorTextKey);
   }
   //rebuild the properties list from the cssText of the Rule
   var PropertiesList = cssRule.cssText.split(';');
   for (var pli in PropertiesList) 
   {
        ruleProperty = new snapsis_CSSRuleProperty();
        ruleProperty.name = PropertiesList[pli].substring(0, PropertiesList[pli].indexOf(':')).replace(/ /g,"").toUpperCase();
        ruleProperty.name = ruleProperty.name.replace(/\r\n/g,"");
        //remove it if it's already there
        Properties.remove(ruleProperty.name);

        if (ruleProperty.name != '')
        {
            ruleValue = new String (PropertiesList[pli].substring(PropertiesList[pli].indexOf(':') + 1,PropertiesList[pli].length ));
            if (ruleProperty.name == "BACKGROUND-IMAGE")
            {
                if (ruleValue.indexOf("url(") != -1 && ruleValue.indexOf("url(/") == -1 && ruleValue.indexOf("url(http") == -1)
                {
                    var pathStart = ruleValue.indexOf("url(") + 4;
                    ruleValue = ruleValue.substring(0,pathStart) + cssRule.Path +  ruleValue.substring(pathStart,ruleValue.length)
                }
            }
            ruleProperty.value = ruleValue;
            Properties.add(ruleProperty.name, ruleProperty);
       }
   }                    
   cssRule.properties = Properties;
   snapsis_CSSRulesList.add(selectorTextKey, cssRule);

}
function snapsis_getCSSRuleProperties(selectorTextKey)
{
    	var RuleProperties = new String();
    	var oRule = snapsis_CSSRulesList.get(selectorTextKey);
        if (oRule)
        {
    		var PropertiesList = oRule.properties.values();
    		for ( var i in PropertiesList )
    		{
    	        var ruleProperty = PropertiesList[i];
    	        if (ruleProperty.name !="")
    	            RuleProperties += ruleProperty.name + ":" + ruleProperty.value +";\r\n"
    		}
		}
		return '{\r\n' + RuleProperties + '}';
}
// Snapsis.Javascript.Utilities
var snapsis_MoveObject = null;
var snapsis_diffX = snapsis_diffY = 0;
var snapsis_xScroll = snapsis_yScroll = 0;
var snapsis_ContainerId=null;
var snapsis_zIndexTop=2000;

function snapsis_dockCSSEditorContainer()
{
    if ( snapsis_CSSViewerActive )
        snapsis_toggleCSSViewer(true);
    
    snapsis_dockContainer('CSSEditorContainer');   
}

function snapsis_CSSToggleDisplay(oContainerId,onoff,AdjustHeight){

        if (AdjustHeight == null)
            AdjustHeight = 0;
		var oContainer=document.getElementById(oContainerId);
		//the iframe is used to hide the list boxes and needs to be adjusted for height
		//if a container is being toggled and the container adds or subtracts from the total height of the form
		var CSSEditorIFrame = document.getElementById("CSSEditorIFrame"); 
		if (oContainer != null)
		{
		    if (onoff == null)
		    {
       		    if ( oContainer.style.display == "block")
    		        onoff = 'off';
    		    else
    		        onoff = 'on';
            }
    	    if ( oContainer.style.display == "block" || onoff.toLowerCase() == 'off')
    	    {
    	       oContainer.style.display = "none";
    	       oContainer.style.visibility = "hidden";
            }
            else
            {
               oContainer.style.display = "block";
               oContainer.style.visibility = "visible";
            }
             CSSEditorIFrame.height = parseInt(CSSEditorIFrame.height) + parseInt(AdjustHeight);
             CSSEditorIFrame.style.height   = CSSEditorIFrame.height;
		}
	return;
}
function snapsis_startMouseMove(){
    var HandleId = new String(event.srcElement.id)
    //the Container being moved needs to have the same id as the handle without the "Handle" suffix
    snapsis_MoveObject = document.getElementById(HandleId.substring(0,HandleId.length - 6));
    document.attachEvent("onmousemove",snapsis_handleMouseMove);
    document.attachEvent("onmouseup",snapsis_cancelMouseMove);
}
function snapsis_cancelMouseMove(){
	document.detachEvent("onmousemove",snapsis_handleMouseMove);
	document.detachEvent("onmouseup",snapsis_cancelMouseMove);
    snapsis_MoveObject = null;
}
function snapsis_handleMouseMove(){

    if ( snapsis_MoveObject )
    {
        snapsis_MoveObject.style.pixelLeft = event.clientX - document.body.scrollLeft ;
        snapsis_MoveObject.style.pixelTop = event.clientY - document.body.scrollTop;
	    event.returnValue = false;
	    event.cancelBubble = true;
    }
}
var snapsis_ToolbarButtonList = new Array();
var snapsis_ToolbarButtonPressed = "";
function snapsis_writeButton(buttonID,caption,clickFunction,imgsrc){
        snapsis_ToolbarButtonList.push(buttonID);
		var html = '<td style="cursor:hand;padding-right:2px;">';
		html +='<div id="'+buttonID+'"';
		html +=' class="ButtonNormal"';
		html +=' onselectstart="ButtonOnSelectStart()"';
		html +=' ondragstart="ButtonOnDragStart()"';
		html +=' onmousedown="ButtonPushButton('+buttonID+'.id)"';
		//html +=' onmouseup="ButtonOnMouseUp('+buttonID+'.id)"';
		html +=' onmouseout="ButtonOnMouseOut('+buttonID+'.id)"';
		html +=' onmouseover="ButtonOnMouseOver('+buttonID+'.id)"';
		html +=" ondblclick='"+clickFunction+"'";
		html +=" onclick='"+clickFunction+"'";
		html += ' ><table cellpadding=0 cellspacing=0 border=0><tr><td>'
		html += ' <img id="bPad1'+buttonID+'"';
		html += ' width=1 height=1></td><td></td><td></td></tr><tr><td></td><td>';
		html += ' <img id="bImg'+buttonID+'" src="'+imgsrc+'"';
		html += ' alt="'+caption+'" >';
		html += '</td><td></td></tr><tr><td></td><td></td><td>'
		html += '<img id="bPad2'+buttonID+'"';
		html += ' width=1 height=1></td></tr></table>';
		html +='</div>';
		html +='</td>';
		document.write(html); 
}
function ButtonOnSelectStart()
{
	window.event.returnValue = false;
}

function ButtonOnDragStart()
{
	window.event.returnValue = false;
}

function ButtonOnMouseOut(buttonID){
	if (buttonID == null){return;}
	if (snapsis_ToolbarButtonPressed == buttonID)
	    eval('document.all.'+buttonID).className = "ButtonPressed";
    else
        eval('document.all.'+buttonID).className = "ButtonNormal";
}

function ButtonOnMouseOver(buttonID){
	if (buttonID == null){return;}	
   	eval('document.all.'+buttonID).className = "ButtonMouseOver";
}

function ButtonPushButton(buttonID){
	if (buttonID == null){return;}	
    ButtonReleaseButtons();
    if (snapsis_ToolbarButtonPressed == buttonID)
    {
	    eval('document.all.'+buttonID).className = "ButtonNormal";
	    snapsis_ToolbarButtonPressed = "";
    }
    else
    {
    	eval('document.all.'+buttonID).className = "ButtonPressed";
    	snapsis_ToolbarButtonPressed = buttonID;
    }	
}

function ButtonReleaseButtons(){
	for ( var i in snapsis_ToolbarButtonList)
	{	
	  buttonID = snapsis_ToolbarButtonList[i];
      eval('document.all.'+buttonID).className = "ButtonNormal";
    }
}
/**
    This is a Javascript implementation of a Hashtable object.
    credit to:
    http://m.synovic.home.att.net/hashtable/hashtable.html
    
    Contructor(s):
     Hashtable()
              Creates a new, empty hashtable
    
    Method(s):
     void clear() 
              Clears this hashtable so that it contains no keys. 
     boolean containsKey(String key) 
              Tests if the specified object is a key in this hashtable. 
     boolean containsValue(Object value) 
              Returns true if this Hashtable maps one or more keys to this value. 
     Object get(String key) 
              Returns the value to which the specified key is mapped in this hashtable. 
     boolean isEmpty() 
              Tests if this hashtable maps no keys to values. 
     Array keys() 
              Returns an array of the keys in this hashtable. 
     void put(String key, Object value) 
              Maps the specified key to the specified value in this hashtable. A NullPointerException is thrown is the key or value is null.
     Object remove(String key) 
              Removes the key (and its corresponding value) from this hashtable. Returns the value of the key that was removed
     int size() 
              Returns the number of keys in this hashtable. 
     String toString() 
              Returns a string representation of this Hashtable object in the form of a set of entries, enclosed in braces and separated by the ASCII characters ", " (comma and space). 
     Array values() 
              Returns a array view of the values contained in this Hashtable. 
            
*/
function Hashtable(){
    this.clear = hashtable_clear;
    this.containsKey = hashtable_containsKey;
    this.containsValue = hashtable_containsValue;
    this.get = hashtable_get;
    this.isEmpty = hashtable_isEmpty;
    this.keys = hashtable_keys;
    this.add = hashtable_add;
    this.remove = hashtable_remove;
    this.size = hashtable_size;
    this.toString = hashtable_toString;
    this.values = hashtable_values;
    this.hashtable = new Array();
}                
/*=======Private hashtable methods for internal use only========*/

function hashtable_clear(){
    this.hashtable = new Array();
}

function hashtable_containsKey(key){
    var exists = false;
    for (var i in this.hashtable) {
        if (i == key && this.hashtable[i] != null) {
            exists = true;
            break;
        }
    }
    return exists;
}

function hashtable_containsValue(value){
    var contains = false;
    if (value != null) {
        for (var i in this.hashtable) {
            if (this.hashtable[i] == value) {
                contains = true;
                break;
            }
        }
    }
    return contains;
}

function hashtable_get(key){
    return this.hashtable[key];
}

function hashtable_isEmpty(){
    return (this.size == 0) ? true : false;
}

function hashtable_keys(){
    var keys = new Array();
    for (var i in this.hashtable) {
        if (this.hashtable[i] != null) 
            keys.push(i);
    }
    return keys;
}

function hashtable_add(key, value){
    if (key == null || value == null) {
        throw "NullPointerException {" + key + "},{" + value + "}";
    }else{
        this.hashtable[key] = value;
    }
}

function hashtable_remove(key){
    var rtn = this.hashtable[key];
    this.hashtable[key] = null;
    return rtn;
}

function hashtable_size(){
    var size = 0;
    for (var i in this.hashtable) {
        if (this.hashtable[i] != null) 
            size ++;
    }
    return size;
}

function hashtable_toString(){
    var result = "";
    for (var i in this.hashtable)
    {      
        if (this.hashtable[i] != null) 
            result += "{" + i + "},{" + this.hashtable[i] + "}\n";   
    }
    return result;
}

function hashtable_values(){
    var values = new Array();
    for (var i in this.hashtable) {
        if (this.hashtable[i] != null) 
            values.push(this.hashtable[i]);
    }
    return values;
}
