﻿// Functions to add edit-in-place functionality. All configurable settings are at the top
// REMEMBER: when calling this from HTML, you must use defer="true" for IE7  !!!

    // Set the variables needed
    var EIPHeaderText   = "Edit in Place"    // The default header text of the editing layer
    var EIPClass        = "EditInPlace";     // The class of elements for the EIP functionality
    var TriggerElement  = "TriggerElement";  // The id of the trigger element
    var HeaderElement   = "EIPHeader";       // The id of the header element
    var InputElement    = "EIPInput";        // The id of the input(s) element
    var CButtonElement  = "EIPCustomButton"; // The id of the custom button element
    var ButtonElement   = "EIPButtons";      // The id of the button(s) element
    var TextareaElement = "EIPText";         // The id of the textarea element
    var CancelElement   = "EIPCancel";       // The id of the cancel element
    var SubmitElement   = "EIPSubmit";       // The id of the submit element
    var EditDivClass    = "EditDiv";         // The id of the editing layer
    var Heights         = [];                // The heights of the editing layer
    Heights["small"]    = "16";              // Small height size of the editing layer
    Heights["medium"]   = "68";              // Medium height size of the editing layer
    Heights["large"]    = "100";             // Large height size of the editing layer
    // The text of the edit div
    var EditDivText     = "<div id='"+TriggerElement+"' style='display: none;'></div>" +
                          "<div class='"+HeaderElement+"' id='"+HeaderElement+"'></div>" +
                          "<div class='"+InputElement+"' id='"+InputElement+"'>" +
                          "<textarea id='"+TextareaElement+"' name='"+TextareaElement+"' style='height: 80px;'>" +
                          "</textarea><br /></div><div class='"+ButtonElement+"' id='"+ButtonElement+"'>" +
                          "<input id='"+SubmitElement+"' name='"+SubmitElement+"' type='submit' value='Save' />" +
                          "<input id='"+CancelElement+"' name='"+CancelElement+"' type='submit' value='Cancel' />" +
                          "</div>";
    
    // --- No settings below this line should need editing. Modify the setting above --- //
    
    // Initialize the global focus element variable, ClickedElement
    var ClickedElement;
    
    // Initialize the global key code variable, KeyCode, to 0
    var KeyCode = 0;
    
    // Create the editing layer, set its text, and append it to the body
    var EditingLayer = document.createElement("div");
    EditingLayer.innerHTML = EditDivText;
    EditingLayer.className = EditDivClass;
    document.body.appendChild(EditingLayer);

    // Get the elments having the EIPClass applied to them. These are the triggers
    Elements = GetElementsByClass(EIPClass);
    
    // Apply mouse over/out and click events to the triggers
    for (i = 0; Elements[i]; i++)    
    {
        // Apply mouse over styles to the Edit-in-Place trigger
        Elements[i].onmouseover = function()
        {
            // Remove any text decoration
            this.style.textDecoration = "none";
            
            // Get the trigger's height
            var Size = GetElementSize(this);
        
            // Add a border to the bottom of the trigger
            this.style.borderBottom = "1px dashed #888";
            
            // Restore the original height to compensate for the added height of the border
            this.style.height = (Size.Height - 1) + "px";
        };
        
        // Apply mouse out styles to the Edit-In-Place trigger
        Elements[i].onmouseout = function()
        {
            // Get the trigger's height
            var Size = GetElementSize(this);
            
            // Remove the border from the trigger
            this.style.borderBottom = "none";
            
            // Subtract from the original height to compensate for the removed height of the border
            this.style.height = Size.Height + "px";
            this.style.height = "auto";
        };

        // Apply the edit in place function to the triggers
        Elements[i].onclick = function()
            {
                // Get the textarea element of the edit div and place it in TextareaElem for ease
                var TextareaElem = new GetElement(TextareaElement);
                
                // Set the trigger element in the editing layer
                GetElement(TriggerElement).innerHTML = this.id;
                
                // Get the clicked element (this) and place it in ClickedElement for use elsewhere
                ClickedElement = this;
                
                // Get the custom attributes from the clicked element (this) and place in ClickedAttr
                var ClickedAttr = GetAttributes(this);
                
                // Determine if a virtual link or the object has been clicked
                if (ClickedAttr["type"] == "link") //** Virtual Link
                {
                    // Load a custom string into the textarea
                    TextareaElem.value = ClickedAttr["customstring"];
                }
                else if (ClickedAttr["type"] == "object") //** Object
                {
                    // Replace breaks with new lines
                    TextareaElem.value = BreakToNewline(this.innerHTML);
                }
                else //** Invalid trigger type
                {
                    // Display debug message
                    alert("The trigger does not have a valid type.");
                    return false;
                }
                
                // Determine if a custom button currently exists
                if (GetElement(CButtonElement)) //** Custom button exists
                {
                    // Remove the custom button
                    GetElement(ButtonElement).removeChild(GetElement(CButtonElement));
                }
                
                // Determine if custom button is set
                if (ClickedAttr["custombutton"]) //** Custom button set
                {
                    var CustomButton = document.createElement("input");
                    CustomButton.type = "button"; // must come before "value" to avoid Opera bug
                    CustomButton.id = CButtonElement;
                    CustomButton.value = ClickedAttr["custombutton"];
                    CustomButton.onclick = function(){eval(ClickedAttr["custombuttonfunction"]+"();");};
                    
                    // Append the custom button
                    GetElement(ButtonElement).appendChild(CustomButton);
                }
                
                // Determine if custom header text is set
                if (ClickedAttr["customheader"]) //** Custom header text set
                {
                    // Set the custom header text
                    GetElement(HeaderElement).innerHTML = ClickedAttr["customheader"];
                }
                else //** Custom header text not set
                {
                    // Set the default header text
                    GetElement(HeaderElement).innerHTML = EIPHeaderText;
                }
                
                // Correctly style the editing layer and textarea
                TextareaElem.style.height = Heights[ClickedAttr["textareasize"]] + "px";
                
                // Display the the editing layer
                EditingLayer.style.display = "block";
                
                // Get the size of the editing layer and position its left attribute
                var EditingLayerSize = GetElementSize(EditingLayer);
                EditingLayer.style.position = "absolute";
                EditingLayer.style.left = Math.ceil((780 - EditingLayerSize.Width) / 2) + "px";
                
                // Determine if custom alignment object is set
                if (ClickedAttr["alignobject"]) //** Custom align object set
                {
                    // Get the position and size of the alignment object
                    var AlignObjectPos = GetElementPosition(GetElement(ClickedAttr["alignobject"]));
                    var AlignObjectSize = GetElementSize(GetElement(ClickedAttr["alignobject"]));
                    
                    // Set the top position of the editing layer
                    EditingLayer.style.top = (AlignObjectPos.Top + Math.ceil(AlignObjectSize.Height  / 2) -
                                             Math.ceil(EditingLayerSize.Height / 2)) + "px";
                }
                else //** Custom align object not set
                {
                    // Get the position of the clicked element
                    var ClickedElementPos = GetElementPosition(ClickedElement);
                    var ClickedElementSize = GetElementSize(ClickedElement);                    
                
                    // Set the top position of the editing layer
                    EditingLayer.style.top = (ClickedElementPos.Top + Math.ceil(ClickedElementSize.Height  / 2) -
                                             Math.ceil(EditingLayerSize.Height / 2)) + "px";
                }

                // If a fixed top position is wanted
                // var WindowOffsets = GetWindowOffsets();
                // EditingLayer.style.top = (WindowOffsets.Y + 175) + "px";
                // If horizontal centering of the entire window is wanted
                // var WindowSize = GetWindowSize();
                // EditingLayer.style.left = Math.ceil((WindowSize.Width - EditingLayerSize.Width) / 2) + "px";
                
                // Resize the textarea element
                TextareaElem.style.width = (EditingLayerSize.Width - 35) + "px";
                
                // Focus the textarea of the editing layer
                TextareaElem.focus();
                
                // Select the text within the textarea
                TextareaElem.select();
                
                // Return false to prevent following links, submitting forms, etc
                return false;
            }
    };
    
    // Apply key down/press functions to editing layer
    GetElement(TextareaElement).onkeydown = KeyPressed;
    GetElement(TextareaElement).onkeypress = KeyPressed;
    
    // Apply the canceling function, CancelEdits, to the canceling element, CancelElement
    GetElement(CancelElement).onclick = CancelEdits;
    
    // Apply the submit function, SubmitEdits, to the submitting element, SubmitElement
    GetElement(SubmitElement).onclick = CompleteEdits;
    
    //-- Called when edits are complete         
    function CompleteEdits()
    {
        // Get the attributes of the clicked element in ClickedElement and place in ClickedAttr
        var ClickedAttr = GetAttributes(ClickedElement);
        
        // Get the text of the textarea in the editing layer and place in Text
        var Text = GetElement(TextareaElement).value;
        
        // Remove spaces fromt the textarea text, Text
        Text = Trim(Text);

        // Determine if the clicked element is a virtual link or an object
        if (ClickedAttr["type"] == "link") //** Virtual link
        {
            // Get the object and place in Object
            var Object = new GetElement(ClickedAttr["objectid"]);
            
            // Get the linked object's text and place in ObjectText
            var ObjectText = Object.innerHTML;
            
            // Get the linked object's class and place in ObjectClass
            var ObjectClass = Object.className;
            
            // Determine if the CustomString is editable !!!!CHECK!!!!!
            if (ClickedAttr["editablecustomstring"] == "true") //** Is editable
            {
                // Set a new custom string
                GetElement(ClickedAttr["objectid"]).innerHTML;
            }
            
        }
        else if (ClickedAttr["type"] == "object") //** Object
        {
            // Get the object and place in Object
            var Object = ClickedElement;
        
            // Place the text in ObjectText
            var ObjectText = ClickedElement.innerHTML;
            
            // Place the class in ObjectClass
            var ObjectClass = ClickedElement.className;
        }
        else //** Invalid trigger type
        {
            // Display debug message and return
            alert("The trigger does not have a valid type.");
            return false;
        }

        // Determine if the textarea text, Text, is the same as the CustomString or ObjectText
        if (Text === ClickedAttr["customstring"] || Text === ObjectText) //** Is the same
        {
            // Run the CancelEdits function
            CancelEdits();
            return false;
        }
        
        // Determine if there are classes in addition to the EIPClass class
        if (ClickedElement.className.replace(EIPClass + " ","") !== "") //** Addt'l classes
        {
            // Evaluate the additional classes
            eval(ClickedElement.className.replace(EIPClass + " ","") + "();");
        }
        
        // Set the text of the object to the new text, converting new lines to breaks
        Object.innerHTML = NewlineToBreak($.stripTagsAttributes(Text, {
        	"tags":"a i b","attributes":"target href"
       }));
        
        // Hide the editing layer
        HideElement(EditingLayer);
        
        // Return false to prevent following links, submitting forms, etc
        return false;
    }
    
    //-- Called when edits are canceled
    function CancelEdits()
    {
        HideElement(EditingLayer);
    }

    // Apply keydown events to the window events
    WindowEvent = window.Event ? true : false;
    if (WindowEvent)
    {
        window.captureEvents(Event.KEYDOWN);
        window.onkeydown = GetKeyCode;
    }
    else
    {
        document.onkeydown = GetKeyCode;
    }

    //-- Called when a key is pressed within the edit layer
    function KeyPressed()
    {
        // Get the attributes of the clicked element
        var ClickedAttr = GetAttributes(ClickedElement);
    
        // Get the newlinesallowed value
        var Newlines = ClickedAttr["newlinesallowed"];
    
        // Determine if "Enter" was pressed and new lines aren't allowed
        if (KeyCode == 13 && Newlines == "false") //** Enter pressed
        {
            // Run CompleteEdits function
            CompleteEdits();
        }
        
        // Set KeyCode to 0
        KeyCode = 0;
    }
