if(typeof alvine == 'undefined') alvine = new Object();
alvine_object_createObjectPath(alvine, 'session.effects');


//Fade
function effects_fade(obj, endOpacity, eventName, speed, angle, callback){
  obj = element_isObject(obj);
  if(!obj) return false;
  
  tmpEffect = new APP_EFFECT('fade');
  var effectID = tmpEffect.effectID;

  alvine_object_createObjectPath(alvine, 'session.effects.'+obj.id+'.data.effects.'+effectID);

  var dataObj = alvine.session.effects[obj.id].data;

  dataObj.parentObject = obj;

  dataObj.callback = callback;

  dataObj.effects[effectID] = tmpEffect;

  var opacity = element_getOpacity(obj);

  if(!isDefined(dataObj.effect_initValues)){
    dataObj.effect_initValues = new Array();
    dataObj.effect_initValues.push(opacity);
    element_resetOpacity(obj);
  }
  
  endOpacity  = (!isNull(endOpacity))?endOpacity:opacity;

  //Object needs to tell current values
  dataObj.effect_getCurrentValues = function(){
    var opacity = element_getOpacity(this.parentObject);
    return Array(opacity.toString());
  };
  
  //optionally set initial Values
  dataObj.effect_init = function(){
    if(isNull(this.effect_initValues[0])) return true;
    element_setOpacity(this.parentObject, this.effect_initValues[0]);
    
    return true;
  }

  //Object do effect
  dataObj.effect_doEffect = function(values, effectID){

    var done = new Array();

    for(var i in values){
      done[i] = false;
      if(!isNull(values[i])){
        element_setOpacity(this.parentObject, values[i]);
        
        if(values[i] == this.effects[effectID].targetValues[i]) done[i] = true;

      } else {
        done[i] = true;
      }
    }

    if(!done[0]) return true;
    
    this.effects[effectID].stop();
    
    if(typeof this.callback != 'function') return true;

    this.callback();
    
    return effectID;
  };
  
  //Add Object to effect and announce Finishing-Values
  var tmpTargetValues = new Array();
  tmpTargetValues.push(endOpacity);
  dataObj.effects[effectID].addObjects(dataObj, null, tmpTargetValues, speed, angle, eventName);

  return dataObj;
}

//Rollout
function effects_rollout(obj, endWidth, endHeight, eventName, speed, angle, center, callback){
  obj = element_isObject(obj);
  if(!obj) return false;
  
  tmpEffect = new APP_EFFECT('rollout');
  var effectID = tmpEffect.effectID;
  
  alvine_object_createObjectPath(alvine, 'session.effects.'+obj.id+'.data.effects.'+effectID);

  var dataObj = alvine.session.effects[obj.id].data;
  dataObj.parentObject = obj;

  dataObj.callback = callback;

  dataObj.effects[effectID] = tmpEffect;

  if(!isDefined(dataObj.effect_initValues)){
    dataObj.effect_initValues = new Array();
    dataObj.effect_initValues.push(element_getWidth(dataObj.parentObject));
    element_resetWidth(dataObj.parentObject);
    dataObj.effect_initValues.push(element_getHeight(dataObj.parentObject));
    element_resetHeight(dataObj.parentObject);
  }
  
  dataObj.effects[effectID] = tmpEffect;
  dataObj.options_center = (center===true)?true:false;
  
  var size = element_getSize(dataObj.parentObject);
  endWidth  = (!isNull(endWidth))?endWidth:size.width;
  endHeight = (!isNull(endHeight))?endHeight:size.height;
  
  //optionally set initial Values
  dataObj.effect_init = function(){
    if(isDefined(this.effect_initValues)){
      element_setWidth(this.parentObject, this.effect_initValues[0]);
      element_setHeight(this.parentObject, this.effect_initValues[1]);
    }    
    return true;
  }
  
  //Object needs to tell current values
  dataObj.effect_getCurrentValues = function(){
    var size = element_getSize(this.parentObject);
    return Array(size.width, size.height);
  };

  //Object do effect
  dataObj.effect_doEffect = function(values, effectID){

    var done = new Array();

    for(var i in values){
      done[i] = false;
      if(!isNull(values[i])){
        if(i==0){
          element_setWidth(this.parentObject, values[i]);
          if(this.options_center) element_centerX(this.parentObject);
        } else {
          element_setHeight(this.parentObject, values[i]);
          if(this.options_center) element_centerY(this.parentObject);
        }
        
        if(values[i] == this.effects[effectID].targetValues[i]) done[i] = true;
        
      } else {
        done[i] = true;
      }
    }

    if(!done[0] || !done[1]) return true;

    this.effects[effectID].stop();
    
    if(typeof this.callback != 'function') return true;

    this.callback();

    return true;
  };
  
  //Add Object to effect and announce Finishing-Values
  var tmpTargetValues = new Array();
  tmpTargetValues.push(endWidth);
  tmpTargetValues.push(endHeight);
  dataObj.effects[effectID].addObjects(dataObj, null, tmpTargetValues, speed, angle, eventName);
  
  return dataObj;
}

//Move
function effects_move(obj, endLeft, endTop, eventName, speed, angle, callback){
  obj = element_isObject(obj);
  if(!obj) return false;
  
  tmpEffect = new APP_EFFECT('move');
  var effectID = tmpEffect.effectID;
  
  alvine_object_createObjectPath(alvine, 'session.effects.'+obj.id+'.data.effects.'+effectID);

  var dataObj = alvine.session.effects[obj.id].data;
  dataObj.parentObject = obj;
  
  dataObj.callback = callback;

  dataObj.effects[effectID] = tmpEffect;
  
  var position = element_getPosition(obj);

  if(isNaN(endLeft) || endLeft==null) {
    endLeft  = position.x;
  }
  if(isNaN(endTop) || endTop==null) {
    endTop  = position.y;
  }
  
  if(!isDefined(dataObj.effect_initValues)){
    dataObj.effect_initValues = new Array();
    dataObj.effect_initValues.push(position.x);
    dataObj.effect_initValues.push(position.y);
  }
  
  //optionally set initial Values
  dataObj.effect_init = function(){
    if(isDefined(this.effect_initValues)){
      element_setLeft(this.parentObject, this.effect_initValues[0]);
      element_setTop(this.parentObject, this.effect_initValues[1]);
    }
    
    return true;
  }
  
  //Object needs to tell current values
  dataObj.effect_getCurrentValues = function(){
    var position = element_getPosition(this.parentObject);
    return Array(position.x, position.y);
  };

  //Object do effect
  dataObj.effect_doEffect = function(values, effectID){

    var done = new Array();

    for(var i in values){
      done[i] = false;
      if(!isNull(values[i])){
        if(i==0){
          element_setLeft(this.parentObject, values[i]);
        } else {
          element_setTop(this.parentObject, values[i]);
        }
        if(values[i] == this.effects[effectID].targetValues[i]) done[i] = true;
      } else {
        done[i] = true;
      }
    }

    if(!done[0] || !done[1]) return true;
    
    this.effects[effectID].stop();

    if(typeof this.callback != 'function') return true;

    this.callback();

    return true;
  };
  
  //Add Object to effect and announce Finishing-Values
  var tmpTargetValues = new Array();
  tmpTargetValues.push(endLeft);
  tmpTargetValues.push(endTop);
  dataObj.effects[effectID].addObjects(dataObj, null, tmpTargetValues, speed, angle, eventName);
  
  return dataObj;
}


//EFFECT
function APP_EFFECT(effectType){

  this.effectType = (isDefined(effectType))?effectType:'rollout';
  this.effectID   = element_buildUniqueObjectID(this);

  this.targetObjects = new Array();

  if(typeof this.intervalList != 'object') this.intervalList = new Object();

  this['stop'] = function(killAll){
    if(killAll){
      for(var i in this.srcObject.effects){
        this.srcObject.effects[i].stop();
      }
    } else {
      if(this.intervalID){
        window.clearInterval(this.intervalID);
        this.intervalID = null;
      }
    }
    return true;
  };

  this['addObjects'] = function(obj, effectID, targetValues, speed, angle, eventName){
    obj = element_isObject(obj);
    if(!obj) return false;
    
    effectID = (isNull(effectID))?this.effectID:effectID;
    this.speed = (isNull(speed))?75:speed;
    this.angle = (isNull(angle))?17:angle;

    //get maximal values
    if(!isDefined(obj.effect_originValues)) obj.effect_originValues = obj.effect_getCurrentValues();
    obj.effect_randomValues     = new Array();
    
    //is value set to 'origin' fallback to originValues
    for(var i in targetValues){
      var commandParts = targetValues[i].toString().split(':');
      switch(commandParts[0]){
        case 'origin':
          targetValues[i] = obj.effect_originValues[i];
          break;
        case 'init':
          targetValues[i] = obj.effect_initValues[i];
          break;
        case 'rand':
          var range = commandParts[1].split(',');
          
          for(var j in range){
            range[j] = element_recalcValue2px(range[j], obj.effect_originValues[i]);
          }
          obj.effect_randomValues[i] = range;
          break;
        default:

          targetValues[i] = element_recalcValue2px(targetValues[i], obj.effect_originValues[i]);

          break;
      }
    }
    this.targetValues = targetValues;
    
    obj.effect_calcNewValues      = this.calcNewValues;

    obj.effect_start = function(effectID){
      if(typeof this.effects[effectID] == 'undefined') return true;
      
      this.effects[effectID].start();
      return true;
    };

    obj.effect_killInterval       = function(){
      this.effects[effectID].stop();
      return true;
    };
    obj.effect_stop               = obj.effect_killInterval;

    this.targetObjects.push(obj.parentObject);
    
    this.srcObject = obj;
    
    //set initial values
    if(!obj.effect_initDone) obj.effect_init();
    obj.effect_initDone = true;
    
    this.eventName = (!isNull(eventName))?eventName:'now';
    if(this.eventName == 'now'){
      this.start();
    } else {
      event_add(obj.parentObject, this.eventName, 'alvine.session.effects["'+obj.parentObject.id+'"].data.effect_start("'+effectID+'")', true);
    }

    return true;
  };

  this['start'] = function(){

    for(var i in this.targetObjects){
      var targetObject = this.targetObjects[i];
      var arrayObject  = alvine.session.effects[targetObject.id].data;
    
      this.initValues = new Array();
      this.initValues = arrayObject.effect_getCurrentValues();

      for(var j in this.targetValues){
        if(typeof arrayObject.effect_randomValues[j] == 'object'){
          var range = arrayObject.effect_randomValues[j];
          var randValue = js_rand(range[0], range[1]);

          this.targetValues[j] = randValue;
        }
      }
      
      this.stop(true);

      this.intervalID = window.setInterval('alvine.session.effects["'+targetObject.id+'"].data.effect_calcNewValues("'+this.effectID+'")', this.speed);
      
    }

    return true;
  };
  
  this['calcNewValues'] = function(effectID){

    var currentValues = this.effect_getCurrentValues();

    for(var i in currentValues){

      if(isNull(currentValues[i])) continue;

      currentValues[i] = parseInt(currentValues[i]);

      var strt = parseInt(this.effects[effectID].initValues[i]);
      var dest = parseInt(this.effects[effectID].targetValues[i]);

      if(currentValues[i] == dest) continue;

      if(strt<dest){
        distance = (currentValues[i]<(dest/2))?currentValues[i]:(dest-currentValues[i]);
      } else {
        distance = (currentValues[i]>(strt/2))?(strt-currentValues[i]):currentValues[i];
      }

      distance = (distance<0)?(distance*(-1)):distance;
      distance = (distance==0)?1:distance;

      var factor = Math.ceil(js_acceleration(distance, this.effects[effectID].angle));

      if(strt<dest){
        if((currentValues[i]+factor)<=dest){
          currentValues[i]+= factor;
        } else {
          currentValues[i] = dest;
        }
      } else {
        if((currentValues[i]-factor)>=dest){
          currentValues[i]-= factor;
        } else {
          currentValues[i] = dest;
        }
      }

    //currentValues[i] = currentValues[i];
    }

    this.effect_doEffect(currentValues, effectID);

    return true;
  };
  
  

  
  return true;
}

//effect-scripts
function effects_slideEffect(srcObject, slideObject, timeout, slideBorder, srcEvent, toggleReverseMode){
  srcObject   = (srcObject)?element_isObject(srcObject):false;
  slideObject = element_isObject(slideObject);
  if(!slideObject) return;

  srcObject.toggleReverseMode = (toggleReverseMode===true)?true:false;
  srcObject.slideObj = slideObject;

  slideBorder = (typeof slideBorder == 'undefined')?'top':slideBorder;
  var slideBorderOffset = slideBorder.split(':');
  slideBorder = slideBorderOffset[0];
  
  slideBorderOffset = (typeof slideBorderOffset[1] != 'undefined')?slideBorderOffset[1]:0;
  srcEvent    = (typeof srcEvent == 'undefined' || srcEvent == null)?'onclick':srcEvent;
  slideObject.timeout = (typeof timeout=='undefined')?0:timeout;

  slideObject.initSize = element_getSize(slideObject);
  slideObject.sourceObject = srcObject;

  var viewPort = (slideObject.parentNode.tagName.toString().toLowerCase()!='body')?element_getSize(slideObject.parentNode):alvine_getViewport();

  slideObject.targetPosition = {
    x:0,
    y:0
  };
  var newLeft, newTop;
  switch(slideBorder){
    case 'top':
      slideBorderOffset = (slideBorderOffset>0)?(slideObject.initSize.height-slideBorderOffset):0;
      newTop = (slideObject.initSize.height*(-1));
      element_setTop(slideObject, newTop);            
      slideObject.initPosition = element_getPosition(slideObject);      
      if(slideObject.initPosition.x<0 || slideObject.initPosition.x>viewPort.width){
        slideObject.initPosition.x = 0;
        element_setLeft(slideObject, slideObject.initPosition.x);
      }
      slideObject.targetPosition.x = slideObject.initPosition.x;
      slideObject.targetPosition.y = (0 - slideBorderOffset);
      break;
    case 'right':
      slideBorderOffset = (slideBorderOffset>0)?(slideObject.initSize.width-slideBorderOffset):0;
      newLeft = viewPort.width;      
      element_setLeft(slideObject, newLeft);
      slideObject.initPosition = element_getPosition(slideObject);
      slideObject.targetPosition.x = ((newLeft-slideObject.initSize.width) + slideBorderOffset);
      if(slideObject.initPosition.y<0 || slideObject.initPosition.y>viewPort.height){
        slideObject.initPosition.y = 0;
        element_setTop(slideObject, slideObject.initPosition.y);
      }
      slideObject.targetPosition.y = slideObject.initPosition.y;
      break;
    case 'bottom':
      slideBorderOffset = (slideBorderOffset>0)?(slideObject.initSize.height-slideBorderOffset):0;
      newTop = viewPort.height;      
      element_setTop(slideObject, newTop);
      slideObject.initPosition = element_getPosition(slideObject);
      if(slideObject.initPosition.x<0 || slideObject.initPosition.x>viewPort.width){
        slideObject.initPosition.x = 0;
        element_setLeft(slideObject, slideObject.initPosition.x);
      }
      slideObject.targetPosition.x = slideObject.initPosition.x;
      slideObject.targetPosition.y = ((newTop-slideObject.initSize.height) + slideBorderOffset);
      break;
    case 'left':
      slideBorderOffset = (slideBorderOffset>0)?(slideObject.initSize.width-slideBorderOffset):0;
      newLeft = (slideObject.initSize.width*(-1));
      element_setLeft(slideObject, newLeft);
      slideObject.initPosition = element_getPosition(slideObject);      
      slideObject.targetPosition.x = (0 - slideBorderOffset);
      if(slideObject.initPosition.y<0 || slideObject.initPosition.y>viewPort.height){
        slideObject.initPosition.y = 0;
        element_setTop(slideObject, slideObject.initPosition.y);
      }
      slideObject.targetPosition.y = slideObject.initPosition.y;
      break;
  }
  

  slideObject.effectChain = function(){
    if(this.alvine_visible===true) return;
    
    var cb = function(){
      var obj = this.parentObject;
      if(obj.timeout==0) return;

      window.setTimeout("effects_move('"+ obj.id +"', '"+ obj.initPosition.x+"', '"+ obj.initPosition.y +"', 'now', 12, 18)", obj.timeout);
      obj.alvine_visible = false;
      return ;
    };
    effects_move(this, this.targetPosition.x, this.targetPosition.y, 'now', 12, 18, cb);
    this.alvine_visible = true;

    return;
  };

  if(srcObject){
    srcObject[srcEvent] = function(ev){
      if(!ev) ev = window.event;
      if(!this.slideObj.alvine_visible){
        this.slideObj.effectChain();

        if(typeof this.alvine_onShow == 'function') this.alvine_onShow(ev);

      } else {
        if(this.toggleReverseMode) this.slideObj.hide();
      }
    };
  } else {
    slideObject.effectChain();    
  }

  slideObject.hide = function(){
    if(!this.alvine_visible) return;

    effects_move(this, this.initPosition.x, this.initPosition.y, 'now', 12, 18);
    this.alvine_visible = false;

    if(typeof this.sourceObject != 'object') return;
    if(typeof this.sourceObject.alvine_onHide != 'function') return;
   
    this.sourceObject.alvine_onHide();

  }
}


/*****************
* tab slider
******************/
function effects_initTabSlider(obj, activeIndex, equalizeEntrySize){
  obj = element_isObject(obj);

  var alignment = obj.getAttribute('alvine:alignment');
  obj.alvine_alignment = (alignment=='horizontal' || alignment=='h')?'horizontal':'vertical';

  var divList = obj.getElementsByTagName('div');
  activeIndex = (!isNaN(activeIndex))?activeIndex:0;
  obj.alvine_equalizeEntrySize = (equalizeEntrySize===true)?true:false;

  obj.alvine_entries = {};

  var index = 0;
  obj.alvine_entryList = {};
  for(var i=0;i<divList.length;i++){
    var eObj = element_isObject(divList[i]);
    if(!eObj) continue;
    if(!eObj.getAttribute) continue;

    var type = eObj.getAttribute('alvine:type');
    if(type!='entry') continue;

    obj.alvine_entries[eObj.id] = eObj;

    eObj.alvine_parentObject = obj;

    eObj.setAttribute('alvine:index', index);

    eObj.alvine_fold = function(status, plainResize){

      var newWidth  = 0;
      var newHeight = 0;
      if(this.alvine_parentObject.alvine_alignment=='horizontal'){
        newHeight = this.alvine_initSize.height;
        if(!status) newWidth = (this.alvine_parentObject.alvine_equalizeEntrySize)?this.alvine_parentObject.alvine_peak.width:this.alvine_initSize.width;
      } else {
        newWidth = this.alvine_initSize.width;
        if(!status) newHeight = (this.alvine_parentObject.alvine_equalizeEntrySize)?this.alvine_parentObject.alvine_peak.height:this.alvine_initSize.height;
      }

      if(plainResize){
        element_setSize(this.alvine_contentObj, newWidth, newHeight);
      } else {
        effects_rollout(this.alvine_contentObj, newWidth, newHeight, 'now', 12, 24);
      }
    }

    var subList = eObj.getElementsByTagName('div');
    for(var j=0;j<subList.length;j++){
      var subObj = element_isObject(subList[j]);
      if(!subObj) continue;
      if(!subObj.getAttribute) continue;
      var subType = subObj.getAttribute('alvine:type');
      if(!subType) continue;

      if(subType=='head'){
        eObj.alvine_headObj = subObj;
        eObj.alvine_headObj.alvine_parentObject = eObj;
        eObj.alvine_headObj.alvine_listObject = obj;
        eObj.alvine_headObj.onclick = function(ev){
          if(!ev) ev = window.event;
          var index = this.alvine_parentObject.getAttribute('alvine:index');
          this.alvine_listObject.alvine_refreshList(index);

          return true;
        };
      } else if(subType=='content'){
        eObj.alvine_contentObj = subObj;
      }
    }

    obj.alvine_entryList[eObj.id] = eObj;

    index++;
  }

  obj.alvine_setPeaks = function(){
    this.alvine_peak = {
      width:0,
      height:0
    };

    for(var i in this.alvine_entries){
      //find peaks once
      if(this.alvine_entries[i].alvine_initSize) continue;
      this.alvine_entries[i].alvine_initSize = element_getSize(this.alvine_entries[i].alvine_contentObj);

      if(this.alvine_entries[i].alvine_initSize.width>this.alvine_peak.width)   this.alvine_peak.width  = this.alvine_entries[i].alvine_initSize.width;
      if(this.alvine_entries[i].alvine_initSize.height>this.alvine_peak.height) this.alvine_peak.height = this.alvine_entries[i].alvine_initSize.height;
        
    }
  };
    
  obj.alvine_refreshList = function(activeIndex, plainResize){
    activeIndex = (!isNaN(activeIndex))?activeIndex:0;
    plainResize = (plainResize===true)?true:false;

    for(var i in this.alvine_entryList){
      var entry = this.alvine_entryList[i];

      var index = entry.getAttribute('alvine:index');

      if(index==activeIndex){
        entry.alvine_fold(false, plainResize);
      } else {
        entry.alvine_fold(true, plainResize);
      }
    }
  };

  obj.alvine_setPeaks();
  obj.alvine_refreshList(activeIndex, true);
    
}


/*****************
* Dynamic pulldown
******************/

function effects_arrangePulldownStructure(obj, initStatus){
  obj = element_isObject(obj);
  if(!obj) return null;

  initStatus = (typeof initStatus != 'undefined' && initStatus == 'unfolded')?'unfolded':'folded';

  obj.alvine_currentFoldStatus = (initStatus=='folded')?'folded':'unfolded';
  obj.alvine_newFoldStatus = (initStatus=='folded')?'unfolded':'folded';

  effects_buildFoldingStructure(obj);
  effects_activatePulldownStructure(obj);

  event_add(document, 'click', "effects_pulldownResetStructure('"+obj.id+"')");

  return true;
}

function effects_pulldownResetStructure(obj){
  obj = element_isObject(obj);
  if(!obj) return null;

  obj.alvine_resetFolding();

  return true;
}

function effects_pulldownResetFolding(ev){
  if(!ev) ev = window.event;

  this.alvine_resetFolding();

  return true;
}

function effects_pulldownHandleMouseover(ev){
  if(!ev) ev = window.event;

  this.alvine_parentObj.alvine_resetFolding(this);

}

function effects_pulldownHandleMouseout(ev){
  if(!ev) ev = window.event;

  
  if(typeof this.alvine_children != 'object') return;
  if(typeof this.alvine_children.childrenfolder != 'object') return;

  var children = this.alvine_children.childrenfolder;
  for(var i in children){
    children[i].alvine_resetFolding();
  }
  

}


function effects_activatePulldownStructure(obj){

  if(typeof obj.alvine_children == 'undefined') return null;

  for(var type in obj.alvine_children){
    var cType = obj.alvine_children[type];

    for(var id in cType){
      var cChild = cType[id];

      switch(type){
        case 'childrenfolder':

          break;
        case 'childpanel':
          
          //init

          if(typeof cChild.alvine_parentObj.alvine_resetFolding != 'function'){
            cChild.alvine_parentObj.alvine_resetFolding = function(activeObj){
              if(typeof this.alvine_children != 'object') return;
              if(typeof this.alvine_children.childpanel != 'object') return;

              activeObj = element_isObject(activeObj);
              var activeID = null;
              activeID = (activeObj)?activeObj.id:activeID;

              for(var i in this.alvine_children.childpanel){
                var o = this.alvine_children.childpanel[i];
                if(activeID!=null && o.id==activeID) {
                  o.alvine_toggleStatus('unfolded');
                  
                } else {
                  o.alvine_toggleStatus('folded');                
                }

              //                if(typeof o.alvine_children != 'object') continue;
              //                if(typeof o.alvine_children.childrenfolder != 'object') continue;
              //                for(var j in o.alvine_children.childrenfolder){
              //                  o.alvine_children.childrenfolder[j].alvine_resetFolding();
              //                }
              }
            //return true;
            }
          }

          cChild.alvine_currentFoldStatus = cChild.alvine_masterObj.alvine_currentFoldStatus;
          

          if(typeof cChild.alvine_toggleStatus != 'function'){
            cChild.alvine_toggleStatus = function(status){
              status = (typeof status != 'undefined' && status == 'unfolded')?'unfolded':'folded';
              this.alvine_currentFoldStatus = status;

              for(var i in this.alvine_children.childrenfolder){
                var cFolder = this.alvine_children.childrenfolder[i];

                if(this.alvine_currentFoldStatus=='unfolded'){
                  if(!strstr(cFolder.className, 'sfxPulldownFolded') && !strstr(cFolder.className, 'sfxPulldownUnfolded')) {
                    element_addClassName(cFolder, 'sfxPulldownUnfolded');
                  } else {
                    element_replaceClassName(cFolder, 'sfxPulldownFolded', 'sfxPulldownUnfolded');
                  }
                } else if(this.alvine_currentFoldStatus=='folded'){
                  element_replaceClassName(cFolder, 'sfxPulldownUnfolded', 'sfxPulldownFolded');
                }
                element_replaceClassName(cFolder, '  ', ' ');
              }
              this.alvine_newFoldStatus = (this.alvine_currentFoldStatus == 'folded')?'unfolded':'folded';
            };
          }

          cChild.alvine_toggleStatus(cChild.alvine_masterObj.alvine_currentFoldStatus);
          
          //event_add(cChild, 'mouseover', effects_pulldownResetFolding);
          // Erweiterung um jquery
          $(cChild).mouseenter(effects_pulldownHandleMouseover);
          $(cChild).mouseleave(effects_pulldownHandleMouseout);
          //event_add(cChild, 'mouseover', effects_pulldownHandleMouseover);
          //event_add(cChild, 'mouseout', effects_pulldownHandleMouseout);

          break;
        case 'folderswitch':
          if(typeof obj.alvine_children == 'undefined') break;
          if(typeof obj.alvine_children.childrenfolder == 'undefined') {
            element_replaceClassName(cChild, 'sfxPulldownFolded', 'sfxPulldownBlank');
            break;
          }

          break;
        case 'datailfolder':
          break;
      }

      effects_activatePulldownStructure(cChild, cChild.alvine_masterObj.alvine_currentFoldStatus);

    }
  }
  
  return true;
}

/*****************
* Dynamic folding
******************/

function effects_arrangeFoldingStructure(obj, initStatus){
  obj = element_isObject(obj);
  if(!obj) return null;

  initStatus = (typeof initStatus != 'undefined' && initStatus == 'unfolded')?'unfolded':'folded';

  obj.alvine_currentFoldStatus = (initStatus=='folded')?'folded':'unfolded';
  obj.alvine_newFoldStatus = (initStatus=='folded')?'unfolded':'folded';

  effects_buildFoldingStructure(obj);
  effects_activateFoldingStructure(obj);

  return true;
}

function effects_buildFoldingStructure(obj, level){
  obj = element_isObject(obj);
  if(!obj) return null;

  level = (typeof level == 'undefined')?0:level;

  var r = {};
  for(var i in obj.childNodes){
    var cObj = obj.childNodes[i];
    cObj = element_isObject(cObj);
    if(!cObj) continue;
    if(typeof cObj != 'object') continue;
    if(typeof cObj.id == 'undefined') continue;

    var listKey = cObj.getAttribute('alvine:effects');

    if(!listKey || listKey.indexOf('foldingListKey', 0)!=0) continue;

    listKey = listKey.substr(14).toLowerCase();

    if(listKey == '') continue;

    /////code
    if(typeof r == 'undefined') r = {};
    if(typeof r[listKey] == 'undefined') r[listKey] = {};
    if(typeof r[listKey].first == 'undefined') r[listKey].first = cObj;
    if(typeof r[listKey].last == 'undefined') r[listKey].last = {};

    r[listKey].last = cObj;

    element_addClassName(cObj, 'inside');

    cObj.alvine_parentObj = obj;

    cObj.alvine_level = level;
    if(listKey=='childpanel') element_addClassName(cObj, 'level'+level.toString());
    if(typeof obj.alvine_children == 'undefined') obj.alvine_children = new Object();
    if(typeof obj.alvine_children[listKey] == 'undefined') obj.alvine_children[listKey] = new Object();
    obj.alvine_children[listKey][cObj.id] = cObj;
    cObj.alvine_masterObj = (typeof obj.alvine_masterObj == 'undefined')?obj:obj.alvine_masterObj;
    if(listKey=='folderswitch'){
      if(typeof cObj.alvine_masterObj.alvine_masterChildren == 'undefined') cObj.alvine_masterObj.alvine_masterChildren = new Object();
      if(typeof cObj.alvine_masterObj.alvine_masterChildren.folderswitch == 'undefined') cObj.alvine_masterObj.alvine_masterChildren.folderswitch = new Object();
      cObj.alvine_masterObj.alvine_masterChildren.folderswitch[cObj.id] = cObj;
    }    
    ///code
    
    if(typeof cObj.hasChildNodes == 'function' && !cObj.hasChildNodes()) continue;
    var l = level + 1;
    effects_buildFoldingStructure(cObj, l);

  }

  //ersten und letzten Eintrag kennzeichnen
  if(typeof r != 'object') return true;

  for(var i in r){
    var type = r[i];
    if(typeof type != 'object') continue;
    
    element_removeClassName(type.first, 'inside');
    element_addClassName(type.first, 'first');

    element_removeClassName(type.last, 'inside');
    element_addClassName(type.last, 'last');
  }

  return true;
}

function effects_activateFoldingStructure(obj){

  if(typeof obj.alvine_children == 'undefined') return null;
  
  for(var type in obj.alvine_children){
    var cType = obj.alvine_children[type];

    for(var id in cType){
      var cChild = cType[id];

      switch(type){
        case 'childrenfolder':
          break;
        case 'childpanel':
          break;
        case 'folderswitch':
          if(typeof obj.alvine_children == 'undefined') break;
          if(typeof obj.alvine_children.childrenfolder == 'undefined') {
            element_replaceClassName(cChild, 'sfxFolded', 'sfxBlank');
            break;
          }

          //init
          cChild.alvine_currentFoldStatus = cChild.alvine_masterObj.alvine_currentFoldStatus;

          if(typeof cChild.alvine_toggleStatus != 'function'){            
            cChild.alvine_toggleStatus = function(status){
              status = (typeof status != 'undefined' && status == 'unfolded')?'unfolded':'folded';
              this.alvine_currentFoldStatus = status;

              for(var i in this.alvine_parentObj.alvine_children.childrenfolder){
                var cFolder = this.alvine_parentObj.alvine_children.childrenfolder[i];
                if(typeof cFolder.alvine_initSize == 'undefined') cFolder.alvine_initSize = element_getSize(cFolder);
                if(this.alvine_currentFoldStatus=='unfolded'){
                  //element_setHeight(cFolder, cFolder.alvine_initSize.height);
                  element_setHeight(cFolder, 'auto');
                  element_replaceClassName(this, 'sfxFolded', 'sfxUnfolded');
                } else if(this.alvine_currentFoldStatus=='folded'){
                  element_setHeight(cFolder, 0);
                  element_replaceClassName(this, 'sfxUnfolded', 'sfxFolded');
                }
                element_replaceClassName(this, '  ', ' ');
              }
              this.alvine_newFoldStatus = (this.alvine_currentFoldStatus == 'folded')?'unfolded':'folded';
            };
          }

          cChild.alvine_toggleStatus(cChild.alvine_masterObj.alvine_currentFoldStatus);
          
          cChild.onclick = function(ev){
            if(!ev) ev = window.event;
            
            this.alvine_toggleStatus(this.alvine_newFoldStatus);

            //return object_preventDefaultEventBehaviour(ev);
            return true;
          };

          break;
        case 'datailfolder':
          break;
      }

      effects_activateFoldingStructure(cChild, cChild.alvine_masterObj.alvine_currentFoldStatus);

    }
  }
  return true;
}

function effects_toggleFoldingStatusAll(obj, status){
  obj = element_isObject(obj);

  status = (typeof status != 'undefined' && status == 'unfolded')?'unfolded':'folded';
  if(!obj) return status;
  obj.alvine_currentFoldStatus = status;
  if(typeof obj.alvine_masterChildren == 'undefined') return null;

  var children;
  var cFolder;

  if(typeof obj.alvine_masterChildren.folderswitch != 'undefined'){
    children = obj.alvine_masterChildren.folderswitch;

    for(var fid in children){
      cFolder = children[fid];
      if(typeof cFolder.alvine_toggleStatus != 'function') continue;
      cFolder.alvine_toggleStatus(obj.alvine_currentFoldStatus);
    }
  }

  obj.alvine_newFoldStatus = (obj.alvine_currentFoldStatus == 'folded')?'unfolded':'folded';

  if(typeof obj.alvine_toggleButton != 'undefined') obj.alvine_toggleButton.alvine_changeStatusClass(obj.alvine_newFoldStatus);
  return obj.alvine_newFoldStatus;
}

function effects_initToggleListFoldingButton(obj, listObj){
  obj = element_isObject(obj);
  if(!obj) return false;
  if(typeof obj.alvine_initDone != 'undefined' && obj.alvine_initDone == true) return true;
  obj.alvine_initDone = true;

  listObj = element_isObject(listObj);
  if(!listObj) return false;

  obj.alvine_listObj = listObj;
  listObj.alvine_toggleButton = obj;

  if(!strstr(obj.className, 'sfxFolded')) element_addClassName(obj, 'sfxFolded');

  obj.alvine_changeStatusClass = function(status){

    var statusClass  = (status=='folded')?'sfxFolded':'sfxUnfolded';
    var replaceClass = (statusClass=='sfxFolded')?'sfxUnfolded':'sfxFolded';

    element_replaceClassName(this, statusClass, replaceClass);
    element_replaceClassName(this, '  ', ' ');
  };

  event_add(obj, 'click', effects_handleListFoldingToggleClick);

  return true;
}

function effects_handleListFoldingToggleClick(ev){
  if(!ev) ev = window.event;

  effects_toggleFoldingStatusAll(this.alvine_listObj, this.alvine_listObj.alvine_newFoldStatus);

  this.alvine_changeStatusClass(this.alvine_listObj.alvine_newFoldStatus);
  
  this.alvine_oldStatus = this.alvine_newStatus;


  return object_preventDefaultEventBehaviour(ev);
}


//Object hovering


function effects_initHover(obj){
  obj = element_isObject(obj);
  if(!obj) return;
  if(obj.alvine_hoverInitDone) return;


  obj.onmouseover = function(ev){
    if(this.alvine_hover) return true;
    if(!ev) ev = window.event;
    element_addClassName(this, "cdHoverColor");
    this.alvine_hover = true;
    return true;
  };
  obj.onmousemove = obj.onmouseover;
  obj.onmouseout = function(ev){
    if(!ev) ev = window.event;
    element_removeClassName(this, "cdHoverColor");
    this.alvine_hover = false;
    return true;
  };

  obj.alvine_hoverInitDone = true;

  return;
}

function effects_initHighlightTargetCell(srcObj, trgObj){
  srcObj = element_isObject(srcObj);
  if(!srcObj) return;
  
  trgObj = element_isObject(trgObj);
  if(!trgObj) return;

  srcObj.alvine_targetObj = trgObj;

  if(srcObj.alvine_hoverInitDone) return;
  
  srcObj.onmouseover = function(ev){
    if(srcObj.alvine_targetObj.alvine_hover) return true;
    if(!ev) ev = window.event;
    element_addClassName(srcObj.alvine_targetObj, "cdHoverColor");
    srcObj.alvine_targetObj.alvine_hover = true;
    return true;
  };
  srcObj.onmousemove = srcObj.onmouseover;
  srcObj.onmouseout = function(ev){
    if(!ev) ev = window.event;
    element_removeClassName(srcObj.alvine_targetObj, "cdHoverColor");
    srcObj.alvine_targetObj.alvine_hover = false;
    return true;
  };
  
  srcObj.alvine_hoverInitDone = true;

  return;
}

