/*********************************************
CLib: /wcl/zcontrols/window/0.1.4.3/window.js
*********************************************/
var zWindows = new zWindowHandler();

function zWindowHandler()
{

  this.initialize = function(identity,config)
  {
    this.configs[identity] = config;
    this.getWindow(identity);
    this.createMemorizerAjax();
  }

  this.bindEvent = function(userEvent,identity,userfunc)
  {
    var event = identity + '_' + userEvent;
    this.parent.bindEvent(event,userfunc);
  }

  this.triggerEvent = function(userEvent,eventParams)
  {
    var identity = eventParams.identity;
    var event = identity + '_' + userEvent;
    this.parent.triggerEvent(event,eventParams);
  }

  this.toggle = function(identity,positionParam,hideOther)
  {
    this.getWindow(identity);
    if (this.curWindow.getDisplay() == 'block') {
      this.hide(identity);
    } else {
      this.show(identity,positionParam,hideOther);
    }
  }

  this.show = function(identity,positionParam,hideOther)
  {
    var eventParams = {};
    eventParams.identity = identity;
    eventParams.positionParam = positionParam;
    eventParams.hideOther = hideOther;
    this.triggerEvent('onShow',eventParams);

    if (hideOther) {
      this.hideAll(identity);
    }

    this.getWindow(identity);

    if (positionParam) {
      this.curWindow.smartPosition(positionParam);
    }
    this.curWindow.display('block');
    if (this.configs[identity].zindex_update) {
    this.curWindow.set_zIndex(this.cur_zIndex);
    }

    if (this.configs[identity].overlay) {
      this.create_overlay(this.cur_zIndex - 1);
    }

    this.cur_zIndex++;

    if (this.configs[identity].memorize) {
      this.memorize(identity,'show');
    }

    if (this.configs[identity].autofocus) {
      $(this.configs[identity].autofocus).focus();
    }
  }

  this.checkDrag = function(identity)
  {
    this.getWindow(identity);
    this.curWindow.reCheckDrag();
  }

  this.update_zIndex = function(identity)
  {
    this.getWindow(identity);
    this.curWindow.set_zIndex(this.cur_zIndex);
    this.cur_zIndex++;
  }

  this.update_zIndex_FromDrag = function(drag_object)
  {
    var identity = drag_object.element.id.replace('zWindow_','');
    if (this.configs[identity].zindex_update) {
      this.getWindow(identity);
      this.curWindow.set_zIndex(this.cur_zIndex);
      this.cur_zIndex++;
    }
  }

  this.hide = function(identity)
  {
    var eventParams = {};
    eventParams.identity = identity;
    this.triggerEvent('onHide',eventParams);

    this.getWindow(identity);
    this.curWindow.display('none');

    if (this.configs[identity].memorize) {
      this.memorize(identity,'hide');
    }

    if (this.configs[identity].overlay) {
      this.remove_overlay();
    }

    if (this.configs[identity].autoclean) {
      this.curWindow.setContent('&nbsp;');
    }
  }

  this.hideAll = function(except)
  {
    for (x in this.Windows) {
      if (except && except == x) {
        continue;
      }
      this.hide(x);
    }
  }

  this.isVisible = function(identity)
  {
    this.getWindow(identity);
    if (this.curWindow.getDisplay() == 'block') {
      return true;
    } else {
      return false;
    }
  }

  this.getPosition = function(identity)
  {
    this.getWindow(identity);
    return this.curWindow.getPosition();
  }

  this.position = function(identity,x,y,method)
  {
    this.getWindow(identity);
    this.curWindow.position(x,y,method);
  }

  this.positionRelativeTo = function(identity,elemid,x,y,method)
  {
    this.getWindow(identity);
    this.curWindow.positionRelativeTo(elemid,x,y,method);
  }

  this.smartPosition = function(identity,positionParam)
  {
    this.getWindow(identity);
    this.curWindow.smartPosition(positionParam);
  }

  this.setContent = function(identity,content)
  {
    this.getWindow(identity);
    this.curWindow.setContent(content);
  }

  this.setHeaderText = function(identity,headertext)
  {
    this.getWindow(identity);
    this.curWindow.setHeaderText(headertext);
  }

  this.destroy = function(identity)
  {
    this.getWindow(identity);
    this.curWindow.destroy();
    delete(this.Windows[identity]);
  }

  this.removeDrag = function(identity)
  {
    this.getWindow(identity);
    this.curWindow.removeDrag();
  }

  this.memorize = function(identity,action)
  {
    var params = {};

    var position = this.curWindow.getRelativePosition();

    params.action = action;
    params.identity = identity;
    params.posX = position.X;
    params.posY = position.Y;

    var url = this.configs[identity].memorizeURL;

    this.memorizerAjax.request(url,{parameters:params});
  }

  this.create_overlay = function(zIndex)
  {
    var parent_elem = Position.offsetParent(this.curWindow.main_elem);

    if (!$('zwindow_overlay')) {
      var overlay = document.createElement('div');
      overlay.id = 'zwindow_overlay';
      overlay.className = 'zwindow_overlay';
      overlay.style.zIndex = zIndex;
      parent_elem.appendChild(overlay);
    } else {
      var overlay = $('zwindow_overlay');
      overlay.style.zIndex = zIndex;
    }

    var pos = Position.page(parent_elem);
    overlay.style.left = 0 - pos[0];
    overlay.style.top = 0 - pos[1];

    var dim = document.viewport.getDimensions();
    overlay.style.width = dim.width;
    overlay.style.height = dim.height;

    var selects = document.body.getElementsByTagName('select');
    this.disabled_selects = {};

    for (var i in selects) {
      if (!Element.descendantOf(selects[i],this.curWindow.main_elem)) {
        this.disabled_selects[i] = selects[i];
        this.disabled_selects[i].disabled = true;
      }
    }
  }

  this.remove_overlay = function()
  {
    if ($('zwindow_overlay')) {
      var parent_elem = Position.offsetParent(this.curWindow.main_elem);
      parent_elem.removeChild($('zwindow_overlay'));

      for (var i in this.disabled_selects) {
        this.disabled_selects[i].disabled = false;
      }

    }
    this.disabled_selects = {};
  }

  this.getWindow = function(identity)
  {
    if (this.Windows[identity]) {
      this.curWindow = this.Windows[identity];
      this.curWindow.getElemements();
    } else {
      this.createWindow(identity);
    }
  }

  this.createWindow = function(identity)
  {
    if (this.configs[identity] && this.configs[identity]['zindex']) {
      if (this.cur_zIndex < this.configs[identity]['zindex']) {
        this.cur_zIndex = this.configs[identity]['zindex']
      }
    }

    this.curWindow = new zWindow(identity,this.cur_zIndex,this.configs[identity]);
    this.Windows[identity] = this.curWindow;
    this.cur_zIndex++;
  }

  this.createMemorizerAjax = function()
  {
    if (this.memorizerAjax) return;

    var hasMemory = false;
    for (identity in this.configs) {
      if (this.configs[identity].memorize) {
        hasMemory = true;
      }
    }
    if (hasMemory) {
      this.memorizerAjax = new Prowax();
      this.memorizerAjax.setCompleteIgnoreWait(true);
    }
  }

  this.parent = new prw_object();

  this.configs = {};
  this.userEvents = {};
  this.Windows = {};// zWindow objects
  this.curWindow = null; // current zWindow object
  this.cur_zIndex = 1;
  this.memorizerAjax = null;
  this.disabled_selects = {};
}

function zWindow(identity,zIndex,config)
{

  this.getElemements = function()
  {
    this.main_elem = document.getElementById('zWindow_' + this.identity);
    this.content_elem = document.getElementById('zWindow_' + this.identity + '_Content');
    this.headertext_elem = document.getElementById('zWindow_' + this.identity + '_HeaderText');
  }

  this.reCheckDrag = function()
  {
    this.checkDrag();
  }

  this.checkDrag = function()
  {
    if (!this.headertext_elem || !this.headertext_elem.className.match('_draggable')) {
      this.draggable = false;
      return;
    }
    var options = {};
    options.handle = this.headertext_elem;
    options.onStart = this.onDragStart.bind(this);
    options.onEnd = this.onDragEnd.bind(this);

    this.draggable = true;
    this.drag_object = new prw_draggable(this.main_elem,options);
  }

  this.onDragStart = function(drag_object,uevent)
  {
    zWindows.update_zIndex_FromDrag(drag_object);

    var eventParams = {};
    eventParams.identity = this.identity;
    eventParams.drag_object = drag_object;
    eventParams.uevent = uevent;
    zWindows.triggerEvent('onDragStart',eventParams);
  }

  this.onDragEnd = function(drag_object,uevent)
  {
    var eventParams = {};
    eventParams.identity = this.identity;
    eventParams.drag_object = drag_object;
    eventParams.uevent = uevent;
    zWindows.triggerEvent('onDragEnd',eventParams);
  }

  this.removeDrag = function()
  {
    if (!this.draggable) {
      return;
    }
    this.drag_object.destroy();
    this.draggable = false;
    this.drag_object = null;
  }

  this.destroy = function()
  {
    this.removeDrag();
    this.main_elem.parentNode.removeChild(this.main_elem);
  }

  this.getPosition = function()
  {
    var pos = {};
    pos.x = this.main_elem.style.left;
    pos.y = this.main_elem.style.top;
    return pos;
  }

  this.smartPosition = function(positionParam)
  {
    var curDisplay = this.getDisplay();

    this.visibility('hidden');
    this.display('block');


    var tester = $(positionParam);

    if (tester.nodeType && tester.nodeType == 1) {
      var elem = tester;
    } else {
      var elem = Event.element(tester); // event object
    }

    var coords = this.positioner.getAbsoluteCoords(elem);
    var right_x = coords['X'] + Element.getWidth(elem) + 12;
    var left_x = coords['X'] - Element.getWidth(this.main_elem);
    var best_x = right_x;

    var right_result = this.positioner.getAvailableCoords(this.main_elem,right_x,coords['Y'],true);

    if (right_result['X'] != right_x) {
      var left_result = this.positioner.getAvailableCoords(this.main_elem,left_x,coords['Y'],true);
      if (left_result['X'] == left_x) {
        best_x = left_x;
      } else {
        best_x = right_result['X'];
      }
    }

    var final_coords = this.positioner.getRelativeCoords(this.main_elem,best_x,right_result['Y']);

    this.main_elem.style.left = final_coords['X'] + 'px';
    this.main_elem.style.top = final_coords['Y'] + 'px';

    this.visibility('visible');
    this.display(curDisplay);
  }

  this.position = function(abs_x,abs_y,method)
  {
    var curDisplay = this.getDisplay();

    this.visibility('hidden');
    this.display('block');

    if (method == 'ABSOLUTE') {
      var coords = {};
      coords['X'] = abs_x;
      coords['Y'] = abs_y;
    } else {
      var coords = this.positioner.getAvailableCoords(this.main_elem,abs_x,abs_y);
      coords = this.positioner.getRelativeCoords(this.main_elem,coords['X'],coords['Y']);
    }

    this.main_elem.style.left = coords['X'] + 'px';
    this.main_elem.style.top = coords['Y'] + 'px';

    this.visibility('visible');
    this.display(curDisplay);
  }

  this.positionRelativeTo = function(elemid,rel_x,rel_y,method)
  {
    var elem = $(elemid);
    var coords = this.positioner.getAbsoluteCoords(elem);
    this.position(coords['X'] + rel_x,coords['Y'] + rel_y,method);
  }

  this.getRelativePosition = function()
  {
    var coords = {};
    coords.X = this.main_elem.style.left;
    coords.Y = this.main_elem.style.top;
    return coords;
  }

  this.setContent = function(html)
  {
    this.cleanContent();
    this.content_elem.innerHTML = html;
  }

  this.setHeaderText = function(headertext)
  {
    if (this.headertext_elem) {
      this.headertext_elem.innerHTML = headertext;
    }
  }


  this.display = function(value)
  {
    this.main_elem.style.display = value;
  }

  this.visibility = function(value)
  {
    this.main_elem.style.visibility = value;
  }

  this.getDisplay = function()
  {
    return this.main_elem.style.display;
  }

  this.set_zIndex = function(zIndex)
  {
    this.main_elem.style.zIndex = zIndex;
  }

  this.cleanContent = function()
  {
    this.content_elem.innerHTML = '';
  }

  this.identity = identity;
  this.config = config;
  this.main_elem;
  this.headertext_elem;
  this.content_elem;
  this.positioner = new zWindowPositioner();
  this.draggable = false;
  this.drag_object;

  this.getElemements();
  this.set_zIndex(zIndex);
  this.checkDrag();
}

zWindowPositioner = function()
{
  this.positioner = new objectPosition();

  this.getRelativeCoords = function(elem,abs_x,abs_y)
  {
    var scrolls = Position.realOffset(elem);
    var parent_elem = Position.offsetParent(elem);
    var parent_coords = Position.cumulativeOffset(parent_elem);

    var result = {};
    result['X'] = abs_x - parent_coords[0] + scrolls[0];
    result['Y'] = abs_y - parent_coords[1] + scrolls[1];
    return result;
  }

  this.getAbsoluteCoords = function(elem)
  {
    var scrolls = Position.realOffset(elem);
    var coords = Position.cumulativeOffset(elem);
    var result = {};
    result['X'] = coords[0] - scrolls[0];
    result['Y'] = coords[1] - scrolls[1];
    return result;
  }

  this.getAvailableCoords = function(window_elem,x,y,exact)
  {
    return this.positioner.process(window_elem,x,y,exact);
  }

}