/***
Author: TM
Purpose: Class for an expandable and collapsable panel
**/  
function FoldablePanel(){

  this.slide = slide;
  this.changeHeader = changeHeader;
  this.changeTitle = changeTitle;
  /*
  Writes the header of the folding menu
  @element Element doing the change
  @message Message to be displayed, if null, element.value is picked
  */
  function changeHeader(element, message){
       var parent = element.parentNode;
       
       if(!message)
          message = element.value;
       
      
       /*
       while((parent.class == "componentFoldingPanel") == false){
           parent = parent.parentNode;
           if((parent.tagName == "BODY") == true){
              return;
           }
           
       }
       var msg = parent.getElementsByName("foldingPanelHeader_insertTitle");
       if(msg.item(0).firstChild)
           msg.item(0).removeChild(msg.firstChild);
       msg = document.createChild("span");
       var txt = document.createTextNode(message);
       msg.appendChild(txt);
       */
       
  }
  
  function exists(object){
    
    if(typeof(object) != 'undefined' && object != null)
       return true;
       
    return false;
  
  }
  
  function changeTitle(object, newTitle){
      
     
      
      if(!exists(object) || !exists(object.id) || !exists(newTitle))
         return;
         
    
      var iter = 0;   
         
     
      var bodyReg = "Comp_FoldingPanel_$";
      
      while(object != null && iter < 10){
        iter = iter + 1;
       
        if(exists(object.id) && exists(object.id.match(bodyReg))){
        
           var titleDiv = document.getElementById(object.id + "titlePanel");
           if(!exists(titleDiv))
              return;
           titleDiv.innerHTML = newTitle.toString();
           
         
          
          break;
          
        } else if(exists(object.parentNode)){
      
           object = object.parentNode;
      
        } else {
          
          return;
        }
    
      }
   
      
  }
  
  /**
  Sets the checkbox which could be associated with the session
  to keep the box open or not.
  @param folded Should be true or false
  @param body Should be the body of the div.  the id will be used to come up
  with the checkbox Id.
  **/
  
  function setFoldedStatus(folded, body) {
    
   
    if(!exists(body)) {
      return;
    }
    if(!exists(folded)) {
      return; 
    }
    if(!exists(body.id)) {
      return;
    }
    //var id = "_" + body.id + "" + "foldedCheckBox";
    var id = ".*foldedCheckBox";
    var checkBox = document.getElementById(id);
    
    var max = body.childNodes.length;
    var i = 0;
    
    for(; checkBox == null && i < max; i++) {
      var node = body. childNodes[i];
      if(exists(node) && exists(node.id) && node.id.match(id+"$")) {
        checkBox = node;
      }
    }
    if(checkBox == null) {
      return;
    }
    if(!exists(checkBox)) {
      return;
    }
    if(!exists(checkBox.checked)) {
      return;
    }
    checkBox.checked = folded;
    body.isFolded = folded;
    
     
  }
  
  
  /*
  Collapses or expands the panel
  @clickedObject   Object that fires this action
  @animated      boolean, Should slide be animated.
  */
  function slide( clickedObject, animated ){
    
    var subPanel = clickedObject.parentNode;
    var body = (subPanel.childNodes).item(1);
    
    if (document.all) {
      var bUseAnimation = true;
      if (body.style.display == '') {
        body.style.display = 'none';
        bUseAnimation = false;
      } else if (body.style.display == 'none') {
        body.style.display = 'block';
        subPanel.origHeight = parseInt(subPanel.offsetHeight);
        exchangeTitlePicture(clickedObject.childNodes, clickedObject, body);
        return;
      } else if (!bUseAnimation) {
        body.style.display = 'none';
      }
      if (!animated || !bUseAnimation) {
        if (clickedObject.childNodes && clickedObject.childNodes.length > 0) {
          exchangeTitlePicture(clickedObject.childNodes, clickedObject, body);
        }
        return;
      }
    }
    
    var subPanelWidth;
    var subPanelHeight;
    var subPanelStyle;
    var headerStyle;
    var slideTime = 1000;
    var subPanelMaxLength = 100;
    var headerHeight = null;
    
    //Get the current styles
    if(window.getComputedStyle){
      subPanelStyle = window.getComputedStyle(subPanel, null);
      headerStyle = window.getComputedStyle(clickedObject, null);
    } else if (subPanel.currentStyle){
      subPanelStyle = subPanel.currentStyle;
      headerStyle = clickedObject.currentStyle;
    } 
    if(!subPanelStyle || !headerStyle) {
      window.status("Could not compute current style in function slide(arg)");
      return;
    }
    subPanel.style.height = subPanelStyle.height;
    if (!headerHeight) {
      headerHeight = Utils.getComputedHeight(headerStyle);
    }
    
    //Collapse
    
    var bCollapse = true; //(!subPanel.origHeight || parseInt(subPanel.offsetHeight) >= subPanel.origHeight);
    if(typeof(subPanel.expanded) != "undefined" && subPanel.expanded != null ){
       if(subPanel.expanded == true){
         bCollapse = true;
       } else bCollapse = false;
    } else subPanel.expanded = 'false';
    
    if (bCollapse == true) { //collapse     
         subPanel.origHeight = parseInt(subPanel.offsetHeight);
         subPanel.origHeightAuto = "auto";
         subPanel.style.height = parseInt(subPanel.offsetHeight);
         body.style.visibility = "hidden";
         Utils.changeHeight(subPanel, headerHeight, animated);
         
         
    } else { //expand
         subPanel.style.height = headerStyle.height;
         Utils.changeHeight(subPanel, subPanel.origHeight, animated );
         body.style.visibility = "visible"; 
          
    }
    
    if(clickedObject.childNodes && clickedObject.childNodes.length > 0) {
        exchangeTitlePicture(clickedObject.childNodes, clickedObject, body);
     }
      

  }
  
  /***
  Exchanges the image nodes class
  ***/
  function exchangeTitlePicture(imageNodes, header, body){
    
     var i = 0;
     var imageNode; 
     if(imageNodes && imageNodes.length)
     for(i = 0; i < imageNodes.length; i++){
        imageNode = imageNodes.item(i);
        if(imageNode.getAttribute("name") == "image"){
           if(imageNode.className == header.unfoldedImageClass){
               imageNode.className = header.foldedImageClass;
               setFoldedStatus(true, body );
           } else {
               imageNode.className = header.unfoldedImageClass;
               setFoldedStatus(false, body );
           }
        }
     }
  
  }
  
} 
//Readymade object that can be used for the above class.
var foldablePanel = new FoldablePanel();



/***
Author: TM
Purpose: Class with static utility functions
*****/
function Utils(){
}
  /**
  Changes the height of a div
  obj - Div
  animated - Boolean whether collapsing should be timed or not
  toLength - The Length aimed for
  ***/
  Utils.changeHeight = function changeHeight(obj, toLength, animated){
         
         if(obj.intervalTime){
            
           clearInterval(obj.intervalTime);
         }
         toLength = parseInt(toLength);
         var delta = parseInt(obj.style.height) - toLength;
         if(delta == 0)
           return;
         //time = Math.ceil( Math.abs((time / delta )));   
         
         obj.animated = animated;
         obj.expanded = false; 
         obj.acc = 3;  
         obj.addPace = 1; 
         obj.delta = delta;
         obj.intervalTime =  window.setInterval(function(){
           
                     
            if(parseInt(obj.style.height) == toLength || animated == false){
             
               clearInterval(obj.intervalTime);
               
               if(animated == false)
                  obj.style.height = parseInt(toLength) + "px";
                  
               if(obj.expanded == true){
                  obj.style.height = "auto";
               }
              
               return;
            }
            
            else if( parseInt(obj.style.height) > toLength){
                
                //collapse
                obj.expanded = false;
                if((parseInt(obj.style.height) - obj.addPace) <= toLength)
                   obj.style.height = parseInt(toLength) + "px";
                
                else obj.style.height = (parseInt(obj.style.height) - obj.addPace ) + "px";  
                
            } else {
                
                //expand
                obj.expanded = true;
                
                
                if((parseInt(obj.style.height) + obj.addPace) >= toLength)
                   obj.style.height = parseInt(toLength) + "px";
                else obj.style.height = (parseInt(obj.style.height) + obj.addPace ) + "px"; 
               
            }
            
            obj.addPace = obj.acc + obj.addPace;          
           
         },30);
  }
  
  
  // Gets the computed height of an element
  Utils.getComputedHeight = function getComputedHeight(boxElem) {
    var height = 0;
    if(boxElem.height && (boxElem.height).length > 0)
       height = height + parseInt(boxElem.height);
    
    if(boxElem.marginBottom && (boxElem.marginBottom).length > 0)
       height = height + parseInt(boxElem.marginBottom);
    if(boxElem.marginTop && (boxElem.marginTop).length > 0)
       height = height + parseInt(boxElem.marginTop);
    
    if(boxElem.paddingTop && (boxElem.paddingTop).length > 0)
       height = height + parseInt(boxElem.paddingTop); 
    if(boxElem.paddingBottom && (boxElem.paddingBottom).length > 0)
       height = height + parseInt(boxElem.paddingBottom);  
       
    if(boxElem.borderTopWidth && (boxElem.borderTopWidth).length > 0)
       height = height + parseInt(boxElem.borderTopWidth);     
    if(boxElem.borderBottomWidth && (boxElem.borderBottomWidth).length > 0)
       height = height + parseInt(boxElem.borderBottomWidth);
    
    return height;
  }
  
  // Gets the height of an element
  Utils.getHeight = function getHeight(boxElem) {
    var height = boxElem.offsetHeight;
    if (!height) height = 100;
    return height;
  }
  
  /**
  Returns null if object is undefined or null
  **/
  Utils.valCheck = function valCheck(object){
    if(!obect)
       return null;
    return object;
  }