/**
 * This is a class for a slider with a range selection. Based on prototype.js
 * and scriptaculous.js (Dragable). Sorry that there's so man hardcode stuff.
 *
 * Written by Raye
 * raye1010@gmail.com
 * 2010-09-02
 *
 * Sample:
 *  <div id="slider1" style="width:400px;"></div>
 *  <div id="message">
 *    價錢 <span>180</span> 萬 至 <span>230</span> 萬
 *  </div>
 *  <input id="price1" value="180"/>
 *  <input id="price2" value="230"/>
 *
 *  <script>
 *    // callback for slider1, valueFrom, function name must be %sliderDivId%_func1
 *    function slider1_func1(percentage) { // 
 *      var maxValue = 2000;
 *      var showValue = parseInt(2000 * percentage);
 *      $('price1').value = showValue;
 *      $('message').down().update(showValue);
 *    }
 *
 *    // callback for slider1, valueTo, function name must be %sliderDivId%_func2
 *    function slider1_func2(percentage) {
 *      var maxValue = 2000;
 *      var showValue = parseInt(2000 * percentage);
 *      $('price2').value = showValue;
 *      $('message').down().next().update(showValue);
 *    }
 *
 *    // Parameter: divName, imgPath, initRatio1, initRatio2
 *    CreateSlider('slider1', '/century21sk_dev/css/common/', 180/2000, 230/2000);
 *
 */

function RangeSlider(divName, imgPath, initRatio1, initRatio2) {
  this.parentDiv = $(divName);
  this.main;
  this.mask;
  this.arrow1;
  this.arrow2;
  this.imgPath = imgPath;
}

RangeSlider.prototype.init = function () {
  this.main = document.createElement('div');
  $(this.main).setStyle({
    position:'relative',
    width:parseInt(this.parentDiv.getStyle('width')) + 'px',
    height:'15px',
    margin:'0px 5px',
    background:'url("'+this.imgPath+'progressBar.gif") no-repeat scroll 0 -15px transparent'
  });

  this.mask = document.createElement('div');
  $(this.mask).setStyle({
    zIndex: 2,
    position:'absolute',
    left: '0px',
    width:parseInt(this.parentDiv.getStyle('width')) + 'px',
    height:'15px',
    background:'url("'+this.imgPath+'progressBar.gif") no-repeat scroll 0 0 transparent'
  });
  this.main.appendChild(this.mask);

  this.arrow1 = document.createElement('div');
  $(this.arrow1).setStyle({
    zIndex: 5,
    position:'absolute',
    top:'0px',
    left:'-5px',
    width:'10px',
    height:'15px',
    cursor:'e-resize',
    background:'url("'+this.imgPath+'progressArrow.gif")'
  });
  this.main.appendChild(this.arrow1);

  this.arrow2 = document.createElement('div');
    $(this.arrow2).setStyle({
    zIndex: 6,
    position:'absolute',
    top:'0px',
    left:(parseInt(this.parentDiv.getStyle('width')) - 5) + 'px',
    width:'10px',
    height:'15px',
    cursor:'e-resize',
    background:'url("'+this.imgPath+'progressArrow.gif")'
  });
  this.main.appendChild(this.arrow2);

  d1 = new Draggable(this.arrow1, {
    constraint:'horizontal',
    starteffect:null,
    endeffect:null,
    snap: this.arrow1Change
  });

  d2 = new Draggable(this.arrow2, {
    constraint:'horizontal',
    starteffect:null,
    endeffect:null,
    snap: this.arrow2Change
  });
};

// x is the relative x of arrow1
// y is the relative y of arrow1
// dragable is the dragable object, dragable.handle is arrow1
RangeSlider.prototype.arrow1Change = function (x, y, dragable) {
  var x1 = dragable.currentDelta()[0]; // currentDelta returns [x, y]
  var x2 = parseInt($(dragable.handle).up().down().next(1).getStyle('left')); // relative x of arrow2

  var offset = parseInt($(dragable.handle).getStyle('width')) / 2;

  var bound1 = x1 + offset; // center of the arrow
  var bound2 = x2 + offset;

  var mask = $(dragable.handle).up().down();
  mask.setStyle({left:bound1+'px', width:(bound2-bound1)+'px', backgroundPosition:'-'+bound1+'px 0px'});

  var divSlide = $(dragable.handle).up(1);
  eval("if (typeof "+divSlide.id+ "_func1 == 'function') " + divSlide.id + "_func1(" + (bound1 / parseInt(divSlide.getStyle('width'))) + ");");

  return [(x < bound2-offset*2) ? (x > (offset*-1) ? x : (offset*-1)) : bound2-offset*2, 0];
}

RangeSlider.prototype.arrow2Change = function (x, y, dragable) {
  var x1 = parseInt($(dragable.handle).up().down().next(0).getStyle('left')); // relative x of arrow2
  var x2 = dragable.currentDelta()[0]; // currentDelta returns [x, y]

  var offset = parseInt($(dragable.handle).getStyle('width')) / 2;
  var parentWidth = parseInt($(dragable.handle).up().getStyle('width'));

  var bound1 = x1 + offset; // center of the arrow
  var bound2 = x2 + offset;

  var mask = $(dragable.handle).up().down();
  mask.setStyle({width:(bound2-bound1)+'px'});

  var divSlide = $(dragable.handle).up(1);
  eval("if (typeof "+divSlide.id+ "_func2 == 'function') " + divSlide.id + "_func2(" + (bound2 / parseInt(divSlide.getStyle('width'))) + ");");

  return [(x < parentWidth-offset) ? (x > bound1 ? x : bound1) : parentWidth-offset, 0];
}

RangeSlider.prototype.setRange = function (initRatio1, initRatio2) {
  var offset = parseInt(this.arrow1.getStyle('width')) / 2;

  var parentWidth = parseInt(this.parentDiv.getStyle('width'));

  var x1 = parseInt(0 + (offset * -1) + (parentWidth * initRatio1));
  var x2 = parseInt(0 + (offset * -1) + (parentWidth * initRatio2));

  this.arrow1.setStyle({left:x1+'px'});
  this.arrow2.setStyle({left:x2+'px'});

  this.mask.setStyle({left:(x1+offset)+'px', width:(x2-x1)+'px'});
  this.mask.setStyle('backgroundPosition', '-'+x1+'px 0px');
}

RangeSlider.prototype.appendToParent = function () {
  this.parentDiv.appendChild(this.main);
};

function CreateSlider(divName, imgPath, initRatio1, initRatio2) {
  slider = new RangeSlider(divName, imgPath);
  slider.init();
  slider.setRange(initRatio1, initRatio2);
  slider.appendToParent();
  return slider;
}

