/**
 * object.lib.js - insert headline here
 *
 * COPYRIGHT: All  title   and  proprietary  rights,  including  trade
 * secrets,   in   the   Software   and   any   copies thereof and the
 * accompanying  written   materials,   are  owned  by   schukai  GmbH
 * and  are  protected  by  German  copyright  laws,  other applicable
 * copyright   laws  and  international  treaty  provisions.
 *
 * @package    alvine
 * @author     schukai GmbH <info@schukai.de>
 * @copyright  Copyright (C) 2002, 2003, 2004, 2005, 2006 schukai GmbH
 * @license    http://www.alvine.de/license/
 * @version    20061114
 * @link       http://www.alvine.de/
 */

if(typeof alvine == 'undefined') alvine = new Object();
alvine_object_createObjectPath(alvine, 'data.move');

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

  //init moving  
  if(typeof alvine.data.move.object == 'undefined') alvine.data.move.object = null;

  event_add(document, 'mousemove', object_moveObject);
  event_add(document, 'mouseup',   object_toggleMoving);

  //..
  
  return true;
}
 
function object_count(obj){
  
  if(typeof obj != 'object') return 0;
  
  var cnt = 0;
  for(var i in obj){
    cnt++;
  }
  
  return cnt;
}


function alvine_object_addObserver(srcID, targetID, callBackFunction){
  
  var sourceObj = element_isObject(srcID);
  var thisObj = element_isObject(targetID);
    
  if(!sourceObj) return null;
  if(!thisObj) return null;
  
  callBackFunction = (typeof callBackFunction == 'undefined')?'alvine_handleEvent':callBackFunction;
  
  if(typeof thisObj['alvine_observers'] == 'undefined') thisObj['alvine_observers'] = new Object();
  if(typeof thisObj['alvine_observers'][callBackFunction] == 'undefined') thisObj['alvine_observers'][callBackFunction] = new Array();
  
  //Observer Eintrag bauen / hinzufügen
  var newObserver = new Object();
  newObserver.id = srcID;
  
  thisObj['alvine_observers'][callBackFunction].push(newObserver);
  
  
  //Notify Observer Funktion hinzufügen
  if(typeof thisObj.alvine_notifyObserver == 'undefined'){
    thisObj['alvine_notifyObserver'] = function(observerKey, data){
      
      observerKey = (typeof observerKey == 'undefined')?'alvine_handleEvent':observerKey;
      
      if(typeof this.alvine_observers[observerKey] == 'undefined') return false;
      
      var myObservers = this.alvine_observers[observerKey];
      
      if(myObservers.length==0) return false;
      
      if(typeof data == 'undefined') data = new Object();
      
      for(var i in myObservers){
        var entry = myObservers[i];
        var oObj = element_isObject(entry.id);

        oObj[observerKey](data, this);
      }
    
      return true;
    };
  }
  
  
  //wenn die CallBackFunktion nicht vorhanden ist >> anlegen
  if(typeof sourceObj[callBackFunction] == 'undefined'){
    sourceObj[callBackFunction] = function(data, srcObj){
      
      
    
      return true;
    };
  }
  
  return true;

}


function alvine_object_hasObservers(obj){
  obj = element_isObject(obj);
  
  if(typeof obj.alvine_notifyObserver == 'undefined') return false;
  if(typeof obj.alvine_observers == 'undefined') return false;
  
  return true;
}

function alvine_object_createObjectPath(initObject, pathString){
  
  if(typeof initObject != 'object') initObject = document;

  var pathParts = pathString.split('.');
  var newObjName = pathParts.shift();

  if(typeof initObject[newObjName] != 'object') initObject[newObjName] = new Object();

  if(pathParts.length > 0) alvine_element_createObjectPath(initObject[newObjName], pathParts.join('.'));

  return true;
}

function element_buildUniqueObjectID(object){
  obj = object;
  
  if(typeof obj != 'object' && typeof obj != 'function') return null;

  var id = null;
  if(!obj){
    id = (!isNull(object))?object:'generic';
  } else {
    if(isDefined(obj.id) && obj.id!='') {
      id = obj.id;
    } else if(isDefined(obj.tagName)){
      id = obj.tagName.toLowerCase();
    } else if(isDefined(obj.nodeName)){
      id = obj.nodeName.toLowerCase();
    } else if(isDefined(obj.localName)){
      id = obj.localName.toLowerCase();
    }
  }

  var now = new Date();
  var newID = id + '_' + now.getTime() + now.getMilliseconds() + js_rand(0000, 9999);
  
  alvine_object_createObjectPath(alvine, 'session.generatedObjectIDs');

  if(!isDefined(alvine.session.generatedObjectIDs[newID])){
    if(obj && !obj.id) {
      obj.id = newID;
    }
    alvine.session.generatedObjectIDs[newID]  = newID;
  } else {
    newID = element_buildUniqueObjectID(obj);
  }
  return newID;
}

function alvine_getViewport(){
  
  var w = null;
  var h = null;
    
  if(typeof window.innerWidth != 'undefined'){
    w = window.innerWidth;
    h = window.innerHeight;

    return {width:w, height:h};
  }

  if(typeof document.documentElement != 'undefined'
     && typeof document.documentElement.clientWidth != 'undefined' 
     && document.documentElement.clientWidth != 0){
    w = document.documentElement.clientWidth;
    h = document.documentElement.clientHeight;

    return {width:w, height:h};
  }

  if(typeof document.getElementsByTagName('body')[0].clientWidth != 'undefined'){
    w = document.getElementsByTagName('body')[0].clientWidth;
    h = document.getElementsByTagName('body')[0].clientHeight;

    return {width:w, height:h};
  }

  return false;
}

function alvine_object_selectAddOption(selectObj, newString, newValue, selected){
  selectObj = element_isObject(selectObj);
  
  var newOption = document.createElement("option");
  newOption.text     = newString;  
  newOption.value    = newValue;
  if(selected===true) newOption.setAttribute('selected', true);

  if(_ALVINE_IE){ //IE: typeof selectObj.add ist immer Object
	//Objekte vom Typ 'select-one' oder 'select-multiple' sollen eine add-Methode haben^^
	if(selectObj.type != 'select-one' && selectObj.type != 'select-multiple') return false;
  }else{
	if(typeof selectObj.add != 'function') return false;
  }

  try {
    selectObj.add(newOption, null); // standards compliant; doesn't work in IE
  }
  catch(ex) {
    selectObj.add(newOption); // IE only
  }
  
  return true;
}

function alvine_object_selectRemoveOption(selectObj, delValue){
  selectObj = element_isObject(selectObj);
  
  for(var i in selectObj.options){
    var tmpOption = selectObj.options[i];    
    if(tmpOption == null) continue;
    if(!isDefined(tmpOption.value)) continue;
    if(tmpOption.value != delValue) continue;
    
    selectObj.remove(i);
    return true;
  }
  
  return false;
}

function alvine_array_keys(mixed){
  var ret = new Array();
    
  for(var key in mixed) {
    ret.push(key);
  }
  return ret;
}

function alvine_bubble_kSort(mixed, direction){
  
  if(typeof mixed != 'object') return mixed;       
  direction = !direction?'regular':direction;
    
  var x, y, holder;
  var mixedKeys   = alvine_array_keys(mixed);  
  var cKey, nKey;
  for(x = 0; x < mixedKeys.length; x++) {    
    for(y = 0; y < (mixedKeys.length-1); y++) {
      cKey = mixedKeys[y];
      nKey = mixedKeys[y+1];
      var proceed = false;
      
      if(direction=='regular'){
        if(parseInt(cKey) > parseInt(nKey)) proceed = true;
      } else if(direction=='reverse'){
        if(parseInt(cKey) < parseInt(nKey)) proceed = true;
      }
      
      if(!proceed) continue;
      
      holder         = mixedKeys[y+1];
      mixedKeys[y+1] = mixedKeys[y];
      mixedKeys[y]   = holder;
  
    }
  }  
  var ret, mode;
  if(typeof mixed.length == 'undefined'){ 
    //object
    ret = new Object();
    mode = 'object';
  } else {
    //array
    ret = new Array();
    mode = 'array';
  }
  
  for(var i in mixedKeys){
    var key = mixedKeys[i];
    if(mode == 'object'){      
      ret[key] = mixed[key];
    } else if(mode == 'array'){
      ret.push(mixed[key]);
    }      
  }
  
  return ret;
}


/****************moving*/


function object_makeMovable(srcID, moveID, relativePositionObject, lockArea, lockAreaOffset){

  if(_ALVINE_SAFARI==true && _ALVINE_CLIENT_OS=='mac') {
    return false;
  }

  var srcObj = element_isObject(srcID);
  if(!srcObj) return false;
  
  if(typeof srcObj.alvineMovingEnabled != 'undefined') return true;
  
  var moveObj = element_isObject(moveID);

  if(!moveObj) moveObj = srcObj;
  if(!moveObj) return false;
  
  if(typeof lockAreaOffset != 'object') lockAreaOffset = {x:0,y:0};
  moveObj.alvine_lockAreaOffset = lockAreaOffset;
  
  srcObj.alvine_moveObj = moveObj;

  if(typeof moveObj.alvine_onMoveStart != 'function'){
    moveObj.alvine_onMoveStart = function(){

      return true;
    };
  }

  if(typeof moveObj.alvine_onMove != 'function'){
    moveObj.alvine_onMove = function(){

      return true;
    };
  }

  if(typeof moveObj.alvine_onMoveStop != 'function'){
    moveObj.alvine_onMoveStop = function(){

      return true;
    };
  }
  
  moveObj.alvine_lockArea            = (lockArea===true)?true:false;
  moveObj.alvine_relativeParent      = element_isObject(relativePositionObject);
  moveObj.alvine_useRelativePosition = (moveObj.alvine_relativeParent)?true:false;
  moveObj.alvine_initPosition        = element_getPosition(moveObj, moveObj.alvine_useRelativePosition);

  mouse_attachToObject(moveObj);

  event_add(srcObj, 'mousedown', object_toggleMoving);
  event_add(srcObj, 'mouseover', 'element_addClassName("'+srcObj.id+'", "moving_possible")');
  event_add(srcObj, 'mouseout',  'element_replaceClassName("'+srcObj.id+'", " moving_possible", "")');
  
  srcObj.alvineMovingEnabled = true;
  
  return true;

}

function object_digforRelativeParentObject(obj, currentObject){
  obj = element_isObject(obj);
  if(currentObject==null) {
    object_digforRelativeParentObject(obj, obj.parentNode);
    return true;
  }

  if(currentObject.tagName.toString().toLowerCase()=='body') return false;
  
  if(!obj.alvine_relativeParentObject && (currentObject.style.position=='relative' || currentObject.style.position=='absolute')) {
    obj.alvine_relativeParentObject = currentObject;
  } else {
    object_digforRelativeParentObject(obj, currentObject.parentNode);
  }
  return true;
}

function object_getMouseOffset(target, ev){
  if(!ev) ev = window.event;
  if(!target.alvine_getMousePosition) mouse_attachToObject(target);
  var mousePos  = target.alvine_getMousePosition(true, true);

  if(!mousePos) mousePos = {x:0, y:0};

  return mousePos;
}




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

  switch(ev.type){
    case 'mousedown':
      var obj = (!this.alvine_moveObj)?this:this.alvine_moveObj;
      if(typeof obj.alvine_onMoveStart == 'function') obj.alvine_onMoveStart();

      obj.alvine_mouseOffset = object_getMouseOffset(obj, ev);

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

      obj.alvine_currentSize = element_getSize(obj);
      if(obj.alvine_relativeParent) obj.alvine_relativeParent.alvine_currentSize = element_getSize(obj.alvine_relativeParent);
      
      alvine.data.move.object = obj;

      break;
    case 'mouseup':

      if(!alvine.data.move.object) break;

      var obj = alvine.data.move.object;

      if(typeof obj.alvine_onMoveStop == 'function') obj.alvine_onMoveStop();

      obj.alvine_mouseOffset = null;
      obj.alvine_moveStatus  = null;
      
      element_replaceClassName(obj, ' moving_enabled', '');

      alvine.data.move.object = null;
      break;
  }

  return object_preventDefaultEventBehaviour(ev); // NS
}

function object_preventDefaultEventBehaviour(ev){
  //do not behave the default way
  if(typeof ev != 'object') return true;
  if(typeof ev.preventDefault == 'function') ev.preventDefault(); //  Firefox
  ev.returnValue = false; // IE
  return false; // NS
}

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

  if(!alvine.data.move.object) return true;

  var obj = alvine.data.move.object;

  //Just once when start moving
  if(!obj.alvine_moveStatus){
    //code here
    obj.alvine_moveStatus = 'moving';
  }

  if(typeof obj.alvine_onMove == 'function') obj.alvine_onMove();

  var mousePos;
  var left;
  var top;
  var parentSize, objSize;
  if(obj.alvine_relativeParent){
    if(!obj.alvine_relativeParent.alvine_getMousePosition) mouse_attachToObject(obj.alvine_relativeParent);
    mousePos = obj.alvine_relativeParent.alvine_getMousePosition(true, true);

    if(obj.alvine_lockArea){
      parentSize = obj.alvine_relativeParent.alvine_currentSize;
      objSize    = obj.alvine_currentSize;
    }
  } else {
    mousePos = document.alvine_getMousePosition(true, false);   
  }
  left = mousePos.x;
  top  = mousePos.y;

  var mouseOffset = obj.alvine_mouseOffset;

  left-=mouseOffset.x;
  top -=mouseOffset.y;

  var areaOffset = obj.alvine_lockAreaOffset;

  if(obj.alvine_lockArea){
    
    if(left<(areaOffset.x*(-1))) left = (areaOffset.x*(-1));
    if(top <(areaOffset.y*(-1)))  top = (areaOffset.y*(-1));
    
    if(left>(parentSize.width-objSize.width+areaOffset.x)) left = (parentSize.width-objSize.width+areaOffset.x);
    if(top>(parentSize.height-objSize.height+areaOffset.y)) top = (parentSize.height-objSize.height+areaOffset.y);
  }
  element_move(obj, left, top);

  return object_preventDefaultEventBehaviour(ev); // NS
}

function object_storeCaretPosition(obj) {
  obj = element_isObject(obj);
  if(!obj) return true;

  if(document.selection) {
    // Go the IE way
    //obj.alvine_caretPosition = document.selection.createRange().duplicate();
    obj.alvine_caretPosition = document.selection.createRange();
  } else if(obj.selectionStart) {
    // Go the Gecko way
    obj.alvine_caretPosition = obj.selectionStart;
  } else {
    // Fallback for any other browser
  }

  return true;
}

function object_insertAtCaretPosition(obj, contentString) {
  obj = element_isObject(obj);
  if(!obj) return true;

  if(typeof obj.focus != 'undefined'){
    obj.focus();
  }

  if(typeof document.selection != 'undefined') { // Go the IE way
    

    var range = document.selection.createRange();

    range.text = contentString;
    
    /* Anpassen der Cursorposition */
    range = document.selection.createRange();
    range.move('character', contentString);

    //range.select();

  } else if(typeof obj.selectionStart != 'undefined') {  // Go the Gecko way
    /* Find the Start and End Position */
    var start = obj.selectionStart;
    var end   = obj.selectionEnd;

    /* Remember obj is a textarea or input field */
    if(obj.value.length>0){
      obj.value = obj.value.substr(0, start)
        + contentString
        + obj.value.substr(end, obj.value.length);
    } else {
      obj.value = contentString;
    }
  } else {
    // Fallback for any other browser
  }

  if(typeof obj.focus != 'undefined'){
    obj.focus();
  }

  return true;
}

page_onLoad(object_initLibs);

