/*
 * 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_SCROLL] = VegUIScrollbar;

var VUI_P_SCROLL_DIR = 200;
var VUI_P_SCROLL_SPEED = 201;
var VUI_P_SCROLL_STEP = 202;

/******************************************************************************
 * V E G U I  S C R O L L B A R
 *****************************************************************************/
 
/***************************************************/
/** Constructor */

function VegUIScrollbar(refName, Parent, Manager) {
  this.constructor = VegUINode;
  this.constructor(refName, Parent, Manager);
  
  this.type = VUI_SCROLL;
  this.T.scrollDir = 'y';
  
  this.Btn1 = this.add_child('Btn1', VUI_BUTTON);
  this.Btn2 = this.add_child('Btn2', VUI_BUTTON);
  this.Btn3 = this.add_child('Btn3', VUI_BUTTON);
  
  this.Btn1.T.z = 2;
  this.Btn2.T.z = 2;
  this.Btn3.T.z = 0;
  this.T.scrollSpeed = 20;
  this.T.scrollStep = 5;
  
  /* Set up button events */
  this.Btn1.States[VUI_MOUSE_DOWN].Scripts.add(
    function(argArr) { argArr[0].Parent.tgl_scroll(1,0); }
  );
  this.Btn2.States[VUI_MOUSE_DOWN].Scripts.add(
    function(argArr) { argArr[0].Parent.tgl_scroll(1,1); }
  );
  this.Btn1.States[VUI_MOUSE_UP].Scripts.add(
    function(argArr) { argArr[0].Parent.tgl_scroll(0); }
  );
  this.Btn2.States[VUI_MOUSE_UP].Scripts.add(
    function(argArr) { argArr[0].Parent.tgl_scroll(0); }
  );
  this.Btn3.States[VUI_MOUSE_UP].Scripts.add(
    function(argArr) { argArr[0].Parent.tgl_drag(0); }
  );
  this.Btn3.States[VUI_MOUSE_DOWN].Scripts.add(
    function(argArr) { argArr[0].Parent.tgl_drag(1); }
  );
  
  /* method links */
  this.build_scroll = vuiscroll_build;
  this.set_scroll = vuiscroll_set;
  this.is_x = vuiscroll_is_x;
  this.sync = vuiscroll_sync;
  this.link = vuiscroll_link;
  this.overflow = vuiscroll_overflow;
  this.asa = vuiscroll_asa;
  this.scroll = vuiscroll_scroll;
  this.tgl_scroll = vuiscroll_tgl_scroll;
  this.tgl_drag = vuiscroll_tgl_drag;
  this.drag = vuiscroll_drag;
  this.update_content_boundary = vuiscroll_update_content_boundary;
 
  this.disable = vuiscroll_disable;  
  this.set = this.set_scroll;
  this.build = this.build_scroll;
}
VegUIScrollbar.prototype = VegUINode;

/***************************************************/
/** VegUIScrollbar.set_scroll(): Sets scrollbar
  * template properties */
  
function vuiscroll_set(dir, x, y, w, h) {
  if(dir)
    this.T.scrollDir = dir; 
  this.set_node(null, w, h, x, y);
}

/***************************************************/
/** VegUIScrollbar.build_scroll(): Builds scrollbar
  * eleement */
  
function vuiscroll_build(toNode) {
  
  this.dir = this.T.scrollDir;
  
  if(!this.is_x()) {
    this.Btn2.T.bmarg_nr = 0;
    this.Btn3.T.rmarg = 0; 
  } else {
    this.Btn2.T.rmarg_nr = 0;
    this.Btn3.T.bmarg = 0; 
  }
  
  this.scrollSpeed = this.T.scrollSpeed;
  this.scrollStep = this.T.scrollStep;
  
  if(!this.build_node())
    return null;
  
  /* 
   * Set up bounding boxes for button 3
   */

  if(!this.is_x()) {
    this.Btn3.onresize = function() {
      this.BBox.set(
        0,
        this.Parent.Btn1.height(),
        this.Parent.width(),
        this.Parent.asa(),
        true,
        true
      );
    }
  } else {
    this.Btn3.onresize = function() {
      this.BBox.set(
        this.Parent.Btn1.width(),
	0,
	this.Parent.asa(),
	this.Parent.height(),
	true,
        true
      );
    }
  }

  this.sync();
  
  this.Css.overflow = 'hidden';
  this.dock(toNode);
  return 1;
}

/***************************************************/
/** VegUIScrollbar.is_x(): checks dir of scrollbar */

function vuiscroll_is_x() {
  return (this.dir == 'x' ? true : false);
}

/***************************************************/
/** VegUIScrollbar.sync(): Sync Drag button to
  * content and vice versa */
  
function vuiscroll_sync(b) {
  var mod;

  if(!b) {
    /* Sync Scrollbar to content */
    if(!this.is_x()) {
      if(this.overflow() <= 1) {
        /* No content overflow */
        this.Btn3.move(0, this.Btn1.height());
        this.Btn3.resize(0, this.asa()); 
      } else {
        this.Btn3.resize(null, this.asa() / this.overflow());
        mod = ((Math.abs(this.Content.y()) / (this.Content.height() / 100)) * (this.asa() / 100));
        this.Btn3.BBox.enabled = false;
        this.Btn3.move(null, this.Btn1.height() + mod);
        this.Btn3.BBox.enabled = true;
        this.Btn3.BBox.correct();
      }
    } else {
      if(this.overflow() <= 1) {
        this.Btn3.move(this.Btn1.width(), 0);
	this.Btn3.resize(this.asa(), 0);
      } else {
        this.Btn3.resize(this.asa() / this.overflow(), null);
	mod = ((Math.abs(this.Content.x()) / (this.Content.width() / 100)) * (this.asa() / 100));
        this.Btn3.BBox.enabled = false;
	this.Btn3.move(this.Btn1.width() + mod, null);
        this.Btn3.BBox.enabled = true;
        this.Btn3.BBox.correct();
      }
    }
  } else {
    /* Sync Content to scrollbar */
    if(!this.is_x()) {
      mod = 0 - (((this.Btn3.y() - this.Btn1.height()) / (this.asa() / 100)) * (this.Content.height() / 100));
      this.Content.move(null, mod);
    } else {
      mod = 0 - (((this.Btn3.x() - this.Btn1.width()) / (this.asa() / 100)) * (this.Content.width() / 100));
      this.Content.move(mod, null);
    }
  }
  this.disable(this.overflow() <= 1);
}

/****************************************************/
/** VegUIScrollbar.update_content_bounadary(),
  * updates the BBox of the content
  */

function vuiscroll_update_content_boundary() {
  if(!this.Content)
    return;

  var y_diff = this.Content.height() - this.CHolder.height();  
  var x_diff = this.Content.width() - this.CHolder.width();
   
  if(x_diff < 1) x_diff = 0;
  if(y_diff < 1) y_diff = 0;
  
  this.Content.BBox.set(
    (0 - x_diff) - 5,
    (0 - y_diff) - 5,
    this.CHolder.width() + (x_diff * 2) + 5, 
    this.CHolder.height() + (y_diff * 2) + 5,
    true,
    true
  );
}

/***************************************************/
/** VegUIScrollbar.link(): Links scroll bar to 
  * a contentholder and content vegui node element
  * Content needs to be a child of Contentholder
  */

function vuiscroll_link(CHolder, Content) {
  this.CHolder = CHolder;
  this.Content = Content;
  this.update_content_boundary();
  this.sync();
}

/***************************************************/
/** VegUIScrollbar.overflow(): return content
  * overflow in content holder */
  
function vuiscroll_overflow() {
  if(!this.CHolder || !this.Content)
    return 0;
  var res = (!this.is_x() ? (this.Content.height() / this.CHolder.height()) : (this.Content.width() / this.CHolder.width()));
  if(isNaN(res))
    res = 0;
  return res;
}

/***************************************************/
/** VegUIScrollbar.asa(): return active scroll
  * area in bar */

function vuiscroll_asa() {
  return (!this.is_x() ? (this.height() - this.Btn1.height() - this.Btn2.height()) : (this.width() - this.Btn1.width() - this.Btn2.width()));
}

/***************************************************/
/** VegUIScrollbar.scroll(): scrolls content
  * into specified direction */
  
function vuiscroll_scroll(dir) {
  if(!this.is_x()) {
    if(!dir)
      this.Content.move(null, this.Content.y() + this.scrollStep);
    else
      this.Content.move(null, this.Content.y() - this.scrollStep);
  } else {
    if(!dir)
      this.Content.move(this.Content.x() + this.scrollStep, null);
    else
      this.Content.move(this.Content.x() - this.scrollStep, null);
  }

  this.sync();
  if(this.Content.BBox.bumped || this.Btn3.BBox.bumped)
    this.tgl_scroll(0);
}

/***************************************************/
/** VegUIScrollbar.tgl_scroll(): toggle auto scroll
  * mode */

function vuiscroll_tgl_scroll(b, dir) {
  if(b) {
    this.tgl_scroll(0);
    this.scrollInterval = setInterval(this.refName + '.scroll(' + dir + ');', this.scrollSpeed);
  } else {
    clearInterval(this.scrollInterval);
    this.scrollIntervall = null;
  }
}

/***************************************************/
/** VegUIScrollbar.tgl_drag(): toggle drag mode */

function vuiscroll_tgl_drag(b) {
  if(b) {
    var _Scroll = this;
    this.Manager.States[VUI_MOUSE_MOVE].Scripts.add(
      function(argArr) { _Scroll.drag(mouseX, mouseY); },
      'scrldrg'
    );
    this.lastDragX = mouseX;
    this.lastDragY = mouseY;
  } else {
    this.Manager.States[VUI_MOUSE_MOVE].Scripts.free('scrldrg');
  }
  this.bDrag = b;
}

/***************************************************/
/** VegUIScrollbar.drag(): Drag button3 to scroll
  * content */

function vuiscroll_drag(x, y) {
  if(!this.bDrag)
    return;
  
  if(!this.is_x()) {
    this.Btn3.move(null, this.Btn3.y() - (this.lastDragY - y));
    this.lastDragY = y;
  } else {
    this.Btn3.move(this.Btn3.x() - (this.lastDragX - x), null);
    this.lastDragX = x;
  }
  this.sync(1);
}

/****************************************************/
/** VegUIScrollbar.disable(): Disables element */

function vuiscroll_disable(b) {
  this.disable_node(b);
  this.Btn1.disable(b);
  this.Btn2.disable(b);
  this.Btn3.disable(b);
}


