

function calcNewValue(current,destination,step,smooth){
	var acceleration = 8;
  var deceleration = 16;
  
  //calc differende and direction
	var diff = calcDifference(destination,current);
  
  //if y reached destination Value, return
  if(diff.direction > 0){
    if((current + step >= destination) || (current >= destination)){
      return {newvalue:destination,newstep:0};
    }
  }
  
  if(diff.direction < 0){ 
    if((current - step <= destination) || (current <= destination)){
      return {newvalue:destination,newstep:0};
    }
  }
  
  //select minimum of difference and step
  var handleStep = Math.min(diff.difference,step);
  
  //calc new step  
  if(smooth==true) {
    
    //smoothing
    if(handleStep<=diff.difference){
      handleStep+= acceleration;
    } else {
      if(handleStep>=(deceleration*2)){
        handleStep-= deceleration;
      } else {        
        handleStep-= 1;
      }
    }
    
  }
  
  //calc new value
  var handlevalue = parseInt(current) + (diff.direction * parseInt(handleStep));
	
	return {newvalue:handlevalue,newstep:handleStep};
}


function calcDifference(value1,value2){

  value1 = Number(value1);
  value2 = Number(value2);

	var retdiff = parseInt(value1 - value2);

	//consider which direction to go
	var retdirection = 1;
	if (value1 < value2) retdirection = -1;
  retdiff = parseInt(retdirection * Number(retdiff));
  
  return {difference:retdiff,direction:parseInt(retdirection)};
}



/************Klassen */

/*** globale Funktionen(Benutzung in allen Klassen möglich) */
universal_registerFollowingObject = function(object){
  object = isObject(object);
  
  //registers following Objects (with method 'start')
  if(typeof object.start == 'undefined') return true;
  
  this.followingObjects[(this.followingObjects.length+1)] = object;
  
  return true;
}

universal_callFollowingObjects = function(){
  //calls following Objects (with method 'start')
   
  for(var i in this.followingObjects){
    if(typeof this.followingObjects[i].start == 'undefined') continue;

    this.followingObjects[i].start();
  }
  return true;
}

universal_reset = function(object){

  clearInterval(object.current_intervalID);  //timeout zurücksetzen

  if(object.status_open){
    setElementHeight(object.object,'auto');    
  }
    
  if(object.followingObjects.length==0) return true;

  object.callFollowingObjects();
  
  return true;
}

function universal_start(){
  //starts the Effect
 
  //set timer  
  this.current_intervalID      = setInterval(this.objectPoolName+"['"+this.oid+"'].doEffect('"+this.oid+"')",this.init_speed);
  
  return true;
}


/* In JavaScript werden Klassen durch ihren Konstruktor repräsentiert. */

/***************************************************************
*  FADER
***************************************************************/
var FadeObjects = new Object();
function JAVASCRIPT_EFFECT_FADE(object,destOpacity,speed,step,smooth) {
  object = isObject(object);   
  if (typeof object != 'object') return true;
  
  this.objectPoolName          = 'FadeObjects';
  this.object                  = object;
  this.oid                     = buildUniqueObjectID(object);
  this.init_destOpacity        = destOpacity!=''?recalcValue2px(destOpacity,100):'100';
  this.init_speed              = speed!=''?speed:65;
  this.init_step               = step!=''?step:8;
  this.init_smooth             = smooth!=''?smooth:true;
  
  this.current_opacity         = getOpacity(object);
  this.current_step            = this.init_step;
  
  this.current_intervalID      = null;
  
  this.followingObjects        = new Array(); 
  
  /// register Functions 
  this.doEffect                = JAVASCRIPT_EFFECT_FADE_doEffect;
  this.start                   = universal_start;
  this.reset                   = universal_reset;
  this.registerFollowingObject = universal_registerFollowingObject;
  this.callFollowingObjects    = universal_callFollowingObjects;

  FadeObjects[this.oid] = this;
  
  return true;
}

JAVASCRIPT_EFFECT_FADE_doEffect = function(oid){

  var parentObject = FadeObjects[oid];

  var diff = calcDifference(parentObject.init_destOpacity,parentObject.current_opacity);

  // if destination-opacity is reached, return
  if(diff.direction > 0){
    if(parentObject.current_opacity >= parentObject.init_destOpacity) {
      parentObject.reset(parentObject);
      return true;
    }
  }else{
    if(parentObject.current_opacity <= parentObject.init_destOpacity) {
      parentObject.reset(parentObject);      
      return true;
    }
  }  

  //get minimum
  var handlestep = Math.min(diff.difference,parentObject.current_step);
  if(handlestep==0) handlestep = 1;
  parentObject.current_step = diff.direction * parseInt(handlestep);
  
  var newOpacity;
  if(parentObject.init_smooth==true) {
    //smoothing
    if(parentObject.current_step>1) parentObject.current_step-= 1;
  }

  parentObject.current_opacity = parentObject.current_opacity + parentObject.current_step;

  //setting opacity
  setOpacity(parentObject.object,parentObject.current_opacity);
  

  return true;
}

/***************************************************************
*  ROLLOUT
****************************************************************/
var RolloutObjects = new Object();
function JAVASCRIPT_EFFECT_ROLLOUT(object,rollStyle,destinationX,destinationY,speed,stepX,stepY,smooth) {
  object = isObject(object);   
  if (typeof object != 'object') return true;
  
  this.objectPoolName          = 'RolloutObjects';
  this.object                  = object;
  this.oid                     = buildUniqueObjectID(object);
  this.init_rollStyle          = rollStyle!=''?rollStyle:'3';

  //Sizes
  this.init_size               = getElementSize(object);    
  this.destinationWidth        = destinationX!=''?parseInt(destinationX):this.init_size.width;
  this.destinationHeight       = destinationY!=''?parseInt(destinationY):this.init_size.height;
  
  //Positions
  this.init_position           = getElementPosition(object);
  this.destinationLeft         = destinationX!=''?recalcValue2px(destinationX,this.init_size.width):this.init_position.x;
  this.destinationTop          = destinationY!=''?recalcValue2px(destinationY,this.init_size.height):this.init_position.y;
  this.visibleThresholdX       = this.init_size.width * (-1);
  this.visibleThresholdY       = this.init_size.height * (-1);
  
  this.init_speed              = speed!=''?parseInt(speed):65;
  this.init_stepX              = stepX!=''?parseInt(stepX):8;
  this.init_stepY              = stepY!=''?parseInt(stepY):8;
  this.init_smooth             = smooth!=''?smooth:true;
  
  this.current_size            = this.init_size;
  this.current_position        = this.init_position;
  this.current_stepX           = this.init_stepX;
  this.current_stepY           = this.init_stepY;
  
  this.status_open             = false;
  
  this.current_intervalID      = null;
  
  this.followingObjects        = new Array(); 
  
  /// register Functions 
  this.doEffect                = JAVASCRIPT_EFFECT_ROLLOUT_doEffect;
  this.setOffset               = JAVASCRIPT_EFFECT_ROLLOUT_setOffset;
  this.setRollout              = JAVASCRIPT_EFFECT_ROLLOUT_setRollout;
  this.start                   = universal_start;
  this.reset                   = universal_reset;
  this.registerFollowingObject = universal_registerFollowingObject;
  this.callFollowingObjects    = universal_callFollowingObjects;

  RolloutObjects[this.oid] = this;
  
  return true;
}

JAVASCRIPT_EFFECT_ROLLOUT_setOffset = function(offsetX,offsetY){
  if(offsetX) this.destinationWidth   += parseInt(offsetX);
  if(offsetY) this.destinationHeight  += parseInt(offsetY);
  
  if(offsetX) this.destinationLeft    += parseInt(offsetX);
  if(offsetY) this.destinationTop     += parseInt(offsetY);
  
  return true;
}

JAVASCRIPT_EFFECT_ROLLOUT_doEffect = function(oid){

  var parentObject = RolloutObjects[oid];
    
  var destXCalc;
  var destYCalc;
  var current_x = null;
  var current_y = null;
  
  
  switch (parentObject.init_rollStyle) {
    case 1:  
    case 'clip':  
      
      current_x = parentObject.current_size.width;
      current_y = parentObject.current_size.height;
            
      destXCalc = parentObject.destinationWidth;
      destYCalc = destHeight.destinationHeight;
      break;
    case 2:
    case 'size':
      parentObject.current_size = getElementSize(parentObject.object);
      
      current_x = parentObject.current_size.width;
      current_y = parentObject.current_size.height;

      destXCalc = parentObject.destinationWidth;
      destYCalc = parentObject.destinationHeight;
      break;
    case 3:
    case 'slide':
      parentObject.current_position = getElementPosition(parentObject.object);
      
      current_x = parentObject.current_position.x;
      current_y = parentObject.current_position.y;
      
      
      destXCalc = parseInt(parentObject.visibleThresholdX + parentObject.destinationLeft);
      destYCalc = parseInt(parentObject.visibleThresholdY + parentObject.destinationTop);
      
      break;
  }  
  
  var newStepX = parentObject.current_stepX;
  var newStepY = parentObject.current_stepY;

  if(parentObject.current_stepX!=0){
    var nvx = calcNewValue(current_x, destXCalc, parentObject.current_stepX, parentObject.init_smooth);
    destXCalc = nvx.newvalue;
    newStepX = nvx.newstep;
  }

  if(parentObject.current_stepY!=0){
    var nvy = calcNewValue(current_y, destYCalc, parentObject.current_stepY, parentObject.init_smooth);
    destYCalc = nvy.newvalue;
    newStepY = nvy.newstep;
  }

  if(parentObject.current_stepX == 0 && parentObject.current_stepY == 0) {
    parentObject.status_open = false;
    if(parentObject.init_size.height<parentObject.destinationHeight){
      parentObject.status_open = true;
    }
    parentObject.reset(parentObject);
    return true;
  }
  
  //do rolling
  parentObject.setRollout(oid, destXCalc, destYCalc, parentObject.init_rollStyle);
  parentObject.current_stepX = newStepX;
  parentObject.current_stepY = newStepY;
  
  return true;
}

JAVASCRIPT_EFFECT_ROLLOUT_setRollout = function(oid,width,height,style){
  var obj = RolloutObjects[oid].object;

  width = parseInt(width);
  height = parseInt(height);

  switch (style) {
    case 1:
    case 'clip':
      obj.style.clip = 'rect(0px '+width+'px '+height+'px 0px)';
      break;
    case 2:
    case 'size':      
      setElementSize(obj,width,height);
      break;
    default:
    case 3:
    case 'slide':
      moveElement(obj,width,height);
      break;
  }

  return true;
}

/***************************************************************
*  TICKER
***************************************************************/
var TickerObjects = new Object();
function JAVASCRIPT_EFFECT_TICKER(object,rollStyle,destinationX,destinationY,speed,step,smooth) {
  object = isObject(object);   
  if (typeof object != 'object') return true;
  
  this.objectPoolName          = 'TickerObjects';
  this.object                  = object;
  this.oid                     = buildUniqueObjectID(object);
  this.init_rollStyle          = rollStyle!=''?rollStyle:'horizontal';
  
  //Sizes
  this.init_size               = getElementSize(object);    
  this.destinationWidth        = destinationX!=''?recalcValue2px(destinationX,this.init_size.width):this.init_size.width;
  this.destinationHeight       = destinationY!=''?recalcValue2px(destinationY,this.init_size.height):this.init_size.height;
  
  //Positions
  this.init_position           = getElementPosition(object);
  this.destinationLeft         = destinationX!=''?recalcValue2px(destinationX,this.init_position.x):this.init_position.x;
  this.destinationTop          = destinationY!=''?recalcValue2px(destinationY,this.init_position.y):this.init_position.y;
  this.visibleThresholdX       = this.init_position.x * (-1);
  this.visibleThresholdY       = this.init_position.y * (-1);
  
  this.init_speed              = speed!=''?speed:65;
  this.init_step               = step!=''?step:8;
  this.init_smooth             = smooth!=''?smooth:true;
  
  this.current_size            = this.init_size;
  this.current_position        = this.init_position;
  this.current_step            = this.init_step;
  
  this.current_intervalID      = null;
  
  this.followingObjects        = new Array(); 
  
  /// register Functions 
  this.doEffect                = JAVASCRIPT_EFFECT_TICKER_doEffect;
  this.start                   = universal_start;
  this.reset                   = universal_reset;
  this.registerFollowingObject = universal_registerFollowingObject;
  this.callFollowingObjects    = universal_callFollowingObjects;

  TickerObjects[this.oid] = this;
  
  return true;
}

JAVASCRIPT_EFFECT_TICKER_doEffect = function(oid){

  var parentObject = TickerObjects[oid];
    
  

  //do rolling
  //parentObject.setRollout(oid,handle.x,handle.y,parentObject.init_rollStyle);

  return true;
}

