﻿Tree = {};
Tree.ExpandImage = new Image();
Tree.CollapseImage = new Image();

// Default values
Tree.ExpandImage.src = "Library/Images/Icons/ExpandNode.gif";
Tree.CollapseImage.src = "Library/Images/Icons/CollapseNode.gif";

// Toggles a hidden collection of nodes based on
// the id supplied.
// If a second argument is given, this is determined
// to be the id of the accompanying image representing
// the node toggled.  This will be used to toggle the
// src of the image to represent the toggle action.
Tree.ToggleNode = function (collectionId){
    var collection = document.getElementById(collectionId);
    var expanded;
    
    if(collection.style.display == "none"){
        collection.style.display = "block";
        expanded = true;
    } else{
        collection.style.display = "none";
        expanded = false;
    }

    // Toggle image node if second argument is supplied
    if(arguments[1])
        this.ToggleImageNodes(arguments[1], expanded);     
    
    return false;
}

Tree.ExpandNode = function(collectionId){
    var collection = document.getElementById(collectionId);
    collection.style.display = "block";
    
    return false;
}

// Expands or collapses an entire tree supplided with
// the id argument.
// All elements with a class of Expandable will be toggled.
Tree.Toggle = function (id){
    var tree = document.getElementById(id);
    
    if(!tree)
        return;
        
    if(!tree.setExpandedProperty)
    {
        tree.setExpandedProperty = true;
        tree.expanded = true;
    }
     
    var collections = tree.getElementsByTagName("*");
    
    for(var i = 0; i < collections.length; i++){
        if(collections[i].className.indexOf("Expandable") >= 0)
        {
            if(tree.expanded){
                // For the first call to collapse the tree we don't want to 
                // close those collections that have a selected option within it
                if(arguments[2]){
                    var foundSelection = false;
                    var inputs = collections[i].getElementsByTagName("INPUT");
                    
                    for(var x = 0; x < inputs.length; x++){
                        //Debug.WriteLine(collections[i].id + ": " + inputs[x].id + ": " + inputs[x].checked + inputs[x].type);
                        if(inputs[x].type == "checkbox" && inputs[x].checked == true){
                            foundSelection = true;
                            break;  
                        }
                    }
                     
                    if(!foundSelection){
                        collections[i].style.display = "none";
                        this.ToggleImageNode(collections[i].id.replace(/_children/, "_toggle_image"), false); 
                    } 
                } else {
                    collections[i].style.display = "none";
                }  
            }
            else{
                collections[i].style.display = "block";   
            }
        }
    }
    tree.expanded = !tree.expanded;
    
    if(!arguments[2])
        this.ToggleImageNodes(id, tree.expanded);
    
    // If a second argument is supplied toggle value
    // This is used to change text on input to
    // denote whether toggle will Expand or Collapse nodes
    if(arguments[1]){
        var input = document.getElementById(arguments[1]);
        if(input.toggleValue){
            var toggleValue = input.value;
            input.value = input.toggleValue;
            input.toggleValue = toggleValue;
        }
    }
}

// Toggles all images found within the supplied
// element id that are of class Node.
Tree.ToggleImageNodes = function (id, expanded){
    var imgs = document.getElementById(id).getElementsByTagName("IMG");

    for(var i = 0; i < imgs.length; i++){
        if(imgs[i].className.indexOf("Node") >= 0)
        {
            if(expanded){
                imgs[i].src = this.CollapseImage.src;                
            }else{               
                imgs[i].src = this.ExpandImage.src; 
            }             
        }
    }
}

// Toggles an image node
Tree.ToggleImageNode = function(id, expanded){
    var img = document.getElementById(id);
    
    if(img){
        if(expanded){
            img.src = this.CollapseImage.src;                
        }else{               
            img.src = this.ExpandImage.src;  
        }
    }
}

// Sets the value of all checkboxes and radio buttons
// within a particular element to the given value of
// the argument "checked".
function SetState(id, checked){

    var inputs = document.getElementById(id).getElementsByTagName("INPUT");
    
    for(var i = 0; i < inputs.length; i++)
    {
        if((inputs[i].getAttribute("type") == "checkbox") ||
        (inputs[i].getAttribute("type") == "radio"))
        {
            inputs[i].checked = checked;
            continue;
        }
    }
}

// Enables a submit button and disables another as supplied
// in the argument list
function ToggleEnable(enableId, disableId){
    var inputEnable = document.getElementById(enableId);
    var inputDisable = document.getElementById(disableId);
    
    inputEnable.disabled = false;
    inputDisable.disabled = true;
}

// Adds a "select all" node to unordered lists below a given element.
function AddSelectAllNodes(collectionId, cssClass){
    var collections = document.getElementById(collectionId).getElementsByTagName("UL");
    
    for (var i = 0; i < collections.length; i++){
	
        var li = document.createElement("LI");
        li.id  = collections[i].id + "_selectAll";
        li.setAttribute("class", cssClass)
        li.style.backgroundColor = "White";
        var input = document.createElement("INPUT");
        input.type = "checkbox";
        input.targetId = collections[i].id;
        input.id = collections[i].id + "_selectAllBelow";
        input.onclick = function () { SetState(this.targetId, this.checked); setParentState(this.targetId,this.checked);}
        // The following line only works in Mozilla so above two lines are used instead.
        //input.setAttribute("onclick","SetState('" + collections[i].id + "',this.checked);");
				
        var text = document.createElement("span");
        text.innerHTML = "Select all below";
        text.className="";
        text.style.fontWeight = "normal";
        li.appendChild(input);
        li.appendChild(text);
		
        collections[i].insertBefore(li, collections[i].firstChild);
    }
}

// Toggle the checked values of an owner checkbox based on those of it's collection
function toggleCollection(){
    var owner = document.getElementById(this.ownerId);
    var collection = document.getElementById(this.collectionId).getElementsByTagName("INPUT");
    var check = false;
    for(var x = 0; x < collection.length; x++){
            
        if(collection[x].getAttribute("type") == "checkbox"){
            if(collection[x].id.indexOf("_selectAll") < 0 && collection[x] != owner
                && collection[x].checked){
                check = true;
                break;
            }
        }
    }
    owner.checked = check;
}

// General library function to display all the properties of a given object to the document
function WriteProperties(object)
{
    var results;
    for( var i in object)
    {
        results += i + ": " + object[i] + "<br/>";
    }
    document.write(results);
}
// General library function to display all the properties of a given object to a dialog
function ShowProperties(object)
{
    var results;
    for( var i in object)
    {
        results += i + ": " + object[i] + "\n";
    }
    alert(results);
}

// Toggles an attribute which can be used to focus any element
function ToggleFocus(id){
    var element = document.getElementById(id);
    
    if(!element.setFocusedBefore){
        element.setFocusedBefore = true;
        element.focused = false;
    }
    
    if(!element.focused){
        element.focused = true;
        if(document.currentFocus){
            document.currentFocus.style.borderStyle = 'solid';
            document.currentFocus.focused = false;
        }
        document.currentFocus = element;
        element.style.borderStyle = 'dotted';
    } else if(!document.currentFocus || document.currentFocus.id != element.id){
        element.focused = false; 
        document.currentFocus = null;
        element.style.borderStyle = 'solid';
    }
    //Debug.WriteLine(element.id + ': focused = ' + element.focused);
} 

var Search = {};
Search.BufferTimeout = 1000;

Search.Find = function(e){
    if(!Search.Buffer)
        Search.Buffer = '';

    if(!e) e = window.event;

    if(document.currentFocus){
        if(e.keyCode)
            Search.Buffer += String.fromCharCode(e.keyCode);
        else
            Search.Buffer += String.fromCharCode(e.which);
            
        Search.Scan(document.currentFocus.getElementsByTagName('LI'));
        
        // Only last event should delete buffer so need to add some timestamp 
        // for comparison
        Search.RequestTime = new Date();
        setTimeout(Search.ClearBuffer, Search.BufferTimeout);
    }          
}

Search.Scan = function(items){
    if(!Search.Pointer)
        Search.Pointer = 0;

    for(var i = Search.Pointer; i < items.length; i++){
        
        if(items[i].innerText){
            nodeText = items[i].innerText.toLowerCase();
            //Debug.WriteLine(items[i].innerHTML);
        } else {
            nodeText = items[i].textContent.toLowerCase();
            //Debug.WriteLine(items[i].textContent);
        }
        
        if(nodeText.indexOf(Search.Buffer.toLowerCase()) == 0){
            var excluded = false;

            for(var x = 0; x < document.currentFocus.ExclusionList.length; x++){
                if(nodeText.indexOf(document.currentFocus.ExclusionList[x].toLowerCase()) == 0)
                    excluded = true;
            }
            if(!excluded){
                //Debug.WriteLine('Match!!!: ' + items[i].nodeValue + ' with buffer value ' + buffer);
                Search.Pointer = i;
                items[i].scrollIntoView(true);
                break;
            }
        }
    }
}
        
Search.ClearBuffer = function(){
    //Debug.WriteLine('clearing buffer');
    var now = new Date();
    var diff = new Date(now.getTime() - Search.RequestTime.getTime());

    if(Search.BufferTimeout <= (diff.getSeconds() * 1000)){
        Search.Buffer = '';
        Search.Pointer = 0;
    }     
    //Debug.WriteLine('buffer: ' + Search.Buffer);
}