/*
 * vegUI is copyright (c) 2005 Stefan Pratter
 *
 * This file is part of vegUI
 *
 * vegUI is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * vegUI is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with vegUI; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

/******************************************************************************
 * G L O B A L S
 *****************************************************************************/
 
VEGUIOBJ[VUI_WIN] = VegUIWindow;


/* General Settings */

/* Window Shadow color, sets the color of the window shadow
 * (the box that represents the window in move and resize
 * mode
 **/

var WINSHAD_CLASS = 'win_shad';
var VUI_WIN_Z = 0;

/******************************************************************************
 * V E G U I W I N D O W
 *****************************************************************************/
/** Dragable; Resizeable layer with a header element */

/***************************************************/
/** Constructor */

function VegUIWindow(refName, Parent, Manager) {
  this.constructor = VegUINode;
  this.constructor(refName, Parent, Manager);

  /* objects */
  this.type = VUI_WIN;
  this.Skin = this.add_child('Skin', VUI_NODE);
  this.Ui = this.add_child('Ui', VUI_NODE);
  this.Header = this.Ui.add_child('Header', VUI_BUTTON);
  this.Caption = this.Header.add_child('Caption', VUI_NODE);
  this.RC_R = this.Ui.add_child('RC_R', VUI_BUTTON); // Resize Catcher
  this.RC_B = this.Ui.add_child('RC_B', VUI_BUTTON); // Resize Catcher
  this.RC_RB = this.Ui.add_child('RC_RB', VUI_BUTTON); // Resize Catcher
  this.BtnClose = this.Ui.add_child('BtnClose', VUI_BUTTON);
 
  this.Skin.set_marg(0,0);
  this.Ui.set_marg(0,0);
  
  this.RC_R.T.rmarg_nr = -10;
  this.RC_R.T.bmarg = 5;
  this.RC_R.T.w = 13;
  this.RC_R.T.z = 255;
 
  this.RC_B.T.rmarg = 5;
  this.RC_B.T.bmarg_nr = -10;
  this.RC_B.T.h = 13;
  this.RC_B.T.z = 255;

  this.RC_RB.T.rmarg_nr = -10;
  this.RC_RB.T.bmarg_nr = -10;
  this.RC_RB.T.h = 15;
  this.RC_RB.T.w = 15;
  this.RC_RB.T.z = 255;

  this.Header.set_marg(-1);
  this.BtnClose.T.rmarg_nr = 2;
  this.BtnClose.set(0, 2);
  this.Caption.set(null, null, null, 10, 3);

  this.Header.T.h = 20;
  this.Header.T.micon = 'move';
  this.Header.T.z = 20;
  this.BtnClose.T.z = 21;
  
  this.Skin.T.z = 0;
  this.Ui.T.z = 1;

  

  this.Header.States[VUI_MOUSE_DOWN].Scripts.add(
    function(argArr) {argArr[0].Parent.Parent.tgl_drag(1);}
  );
  this.Header.States[VUI_MOUSE_UP].Scripts.add(
    function(argArr) {argArr[0].Parent.Parent.tgl_drag(0);}
  );

  this.BtnClose.States[VUI_MOUSE_DOWN].Scripts.add(
    function(argArr) {argArr[0].Parent.Parent.close();}
  );
 
  this.RC_B.flags = this.RC_RB.flags = (this.RC_R.flags |= VUI_HMOUSE_MOVE);

  this.RC_R.States[VUI_MOUSE_MOVE].Scripts.add(
    function(argArr) { argArr[0].Css.cursor = 'e-resize'; }
  );

  this.RC_B.States[VUI_MOUSE_MOVE].Scripts.add(
    function(argArr) { argArr[0].Css.cursor = 's-resize'; }
  );

  this.RC_RB.States[VUI_MOUSE_MOVE].Scripts.add(
    function(argArr) { argArr[0].Css.cursor = 'se-resize'; }
  );

  this.RC_R.States[VUI_MOUSE_OUT].Scripts.add(
    function(argArr) { argArr[0].Css.cursor = 'default'; }
  );

  this.RC_B.States[VUI_MOUSE_OUT].Scripts.add(
    function(argArr) { argArr[0].Css.cursor = 'default'; }
  );
  
  this.RC_RB.States[VUI_MOUSE_OUT].Scripts.add(
    function(argArr) { argArr[0].Css.cursor = 'default'; }
  );

  this.RC_R.States[VUI_MOUSE_DOWN].Scripts.add(
    function(argArr) { argArr[0].Parent.Parent.tgl_resize(1); }
  );

  this.RC_R.States[VUI_MOUSE_UP].Scripts.add(
    function(argArr) { argArr[0].Parent.Parent.tgl_resize(0); }
  );
  
  this.RC_B.States[VUI_MOUSE_DOWN].Scripts.add(
    function(argArr) { argArr[0].Parent.Parent.tgl_resize(1); } 
  );
  
  this.RC_B.States[VUI_MOUSE_UP].Scripts.add(
    function(argArr) { argArr[0].Parent.Parent.tgl_resize(0); }
  );

  this.RC_RB.States[VUI_MOUSE_DOWN].Scripts.add(
    function(argArr) { argArr[0].Parent.Parent.tgl_resize(1); } 
  );
  
  this.RC_RB.States[VUI_MOUSE_UP].Scripts.add(
    function(argArr) { argArr[0].Parent.Parent.tgl_resize(0); } 
  );

  /*
   * Create Global Window Shadow if it has not been spawned yet
   */

  if(!this.Manager.WinShadow && this.Manager.Base) {
    this.Manager.WinShadow = this.WinShadow = this.Manager.add_child('WinShadow', VUI_NODE);
    this.WinShadow.T.className = WINSHAD_CLASS;
    this.Manager.build_element(this.WinShadow);
    this.WinShadow.hide(1);
  } else
    this.WinShadow = this.Manager.WinShadow;

  this.flags |= VUI_HMOUSE_DOWN;
  this.States[VUI_MOUSE_DOWN].Scripts.add(
    function(argArr) { argArr[0].set_focus(); }
  );

  /* method links */
  this.set_win = vuiwin_set;
  this.build_win = vuiwin_build;
  this.set_caption = vuiwin_set_caption;  
  this.tgl_drag = vuiwin_tgl_drag;
  this.drag = vuiwin_drag;
  this.tgl_resize = vuiwin_tgl_resize;
  this.mresize = vuiwin_mresize;
  this.set_focus = vuiwin_set_focus;
  this.put_shadow = vuiwin_put_shadow;
  this.close = vuiwin_close;
  this.show = vuiwin_show;

  /* wrappers */
  this.set = this.set_win;
  this.build = this.build_win;

  this.Manager.W[this.Manager.winIdx++] = this;
  this.winIdx = this.Manager.winIdx;
}
VegUIWindow.prototype = VegUINode;

/***************************************************/
/** VegUIWindow.set(): sets template properties
  * for window before build() */

function vuiwin_set(title, w, h, x, y) {
  if(title) this.T.winTitle = title;
  this.set_node(null, w, h, x, y);
}

/***************************************************/
/** VegUIWindow.build(): Builds window */

function vuiwin_build(toNode) {
  if(!this.build_node())
    return null;
  this.title = this.T.winTitle;
  this.minW = this.T.minW || 0;
  this.maxW = this.T.maxW || 32000;
  this.minH = this.T.minH || 0;
  this.maxH = this.T.maxH || 32000;
  this.set_caption(this.title);
  this.dock(toNode);
  this.set_focus();
  return 1;
}

/***************************************************/
/** VegUIWindow.set_caption(): sets window title */

function vuiwin_set_caption(txt) {
  this.Caption.clear(document.createTextNode(txt));
}

/***************************************************/
/** VegUIWindow.tgl_drag(): toggle window dragging*/

function vuiwin_tgl_drag(b) {
  this.bDrag = b;
  var Win = this;
  if(b) {
    this.Manager.States[VUI_MOUSE_MOVE].Scripts.add(
      function(argArr) { Win.drag(mouseX, mouseY); },
      'windrg'
    );
    this.lastDragX = mouseX;
    this.lastDragY = mouseY;
    this.put_shadow();
  } else {
    this.Manager.States[VUI_MOUSE_MOVE].Scripts.free('windrg');
    this.move(this.WinShadow.x(), this.WinShadow.y());
    this.WinShadow.hide(1);
  }
}

/***************************************************/
/** VegUIWindow.drag(): drag window around :D */

function vuiwin_drag(x, y) {
  if(!this.bDrag)
    return;
  this.WinShadow.move(
    (
      !(this.flags & VUI_NOMOVE_X) ?
      this.WinShadow.x() - (this.lastDragX - x) :
      null
    ),
    (
      !(this.flags & VUI_NOMOVE_Y) ?
      this.WinShadow.y() - (this.lastDragY - y) :
      null
    )
  );
  this.lastDragY = y;
  this.lastDragX = x;
}

/***************************************************/
/** VegUIWindow.tgl_resize(): toggle window resizing
  */

function vuiwin_tgl_resize(b) {
  if(this.bDrag)
    return;
  var cursor;
  var Win = this;

  if(this.RC_R.Css.cursor == 'e-resize')
    cursor = 'e-resize';
  else if(this.RC_B.Css.cursor == 's-resize')
    cursor = 's-resize';
  else if(this.RC_RB.Css.cursor = 'se-resize')
    cursor = 'se-resize';

  this.bResize = b;
  if(b && cursor) {
    this.Manager.States[VUI_MOUSE_MOVE].Scripts.add(
      function(argArr) { Win.mresize(mouseX, mouseY, cursor);},
      'winrsz'
    );
    this.lastDragX = mouseX;
    this.lastDragY = mouseY;
    this.put_shadow();
  } else {
    this.Manager.States[VUI_MOUSE_MOVE].Scripts.free('winrsz');
    this.resize(this.WinShadow.width(), this.WinShadow.height());
    this.WinShadow.hide(1);
  }
}

/***************************************************/
/** VegUIWindow.mresize(): resize window by mouse */

function vuiwin_mresize(x, y, dir) {
  var w = this.WinShadow.width() - (this.lastDragX - x);
  var h = this.WinShadow.height() - (this.lastDragY - y);

  if(dir == 'e-resize' && !(this.flags & VUI_NORESIZE_W) && w >= this.minW && w <= this.maxW)
    this.WinShadow.resize(w, null);
  else if(dir == 's-resize' && !(this.flags & VUI_NORESIZE_H) && h >= this.minH && h <= this.maxH)
    this.WinShadow.resize(null, h);
  else if(dir == 'se-resize') {
    this.WinShadow.resize(
      (
        (!(this.flags & VUI_NORESIZE_W) && w >= this.minW && w <= this.maxW) ?
        this.WinShadow.width() - (this.lastDragX - x) : 
        null
      ),
      ( 
        (!(this.flags & VUI_NORESIZE_H) && h >= this.minH && h <= this.maxH) ?
        this.WinShadow.height() - (this.lastDragY - y) :
        null
      )
    );
  }
  this.lastDragX = x;
  this.lastDragY = y;
}

/***************************************************/
/** VegUIWindow.set_focus(): sets focus on window
  * and brings it to foreground
  */

function vuiwin_set_focus() {
  var w, i = VUI_WIN_Z;
  for(w in this.Manager.W) {
    this.Manager.W[w].set_pos(null, i++); 
  }
  this.set_pos(null, i);
}

/***************************************************/
/** VegUIWindow.put_shadow(): puts shadow around
  * window that will represent it in resize and
  * move mode
  */

function vuiwin_put_shadow() {
  this.WinShadow.set_pos('absolute', this.Css.zIndex + 1);
  this.WinShadow.resize(this.width(), this.height());
  this.WinShadow.move(this.x(), this.y());
  this.WinShadow.hide(0);
}

/***************************************************/
/** VegUIWindow.close(): Closes Window */

function vuiwin_close() {
  if((this.flags & VUI_KILL_ON_CLOSE)) {
    this.kill();
  } else
    this.hide(1);
}

/***************************************************/
/** VegUIWindow.show(): Shows Window again after
  * closing it 
  */

function vuiwin_show() {
  this.hide(0);
}
