﻿
//
// Virtual Homes Slider Widget
//
// Single value or dual mode (min/max) slider of integers
//

var activePDiv = null;
var activeLeft = null;
var activeClientX = null;
var activeControlIdx = null;

/*
 * Constructor
 *
 * el: DIV element of class "VHSlider"
 * type: "single" or "dual"
 * cb: callback function: cb(val) for "val" type or cb(min,max) for "dual" type
 */
function VHSlider (el, prec, cb) {
    this.DivEl      = el;
    this.Prec       = prec;
    this.Min        = MINPRICE_DEFAULT;
    this.Max        = MAXPRICE_DEFAULT;
    this.OnChangeCB = cb;
    //
    this.pdiv = el;
    this.pdivWidth = 254;  // HARD-WIRED
    el.style.width = this.pdivWidth + "px";
    //
    this.pxWidth  = new Array();
    this.Value    = new Array();
    this.pxMin    = new Array();
    this.pxMax    = new Array();
	this.ImgElements = el.getElementsByTagName('img');
    switch (this.ImgElements.length) {
    case 1:
      this.IsDual     = false;
      this.pxWidth[0] = 14;  // HARD-WIRED
      this.Value[0]   = this.Min;
      this.pxMin[0]   = 0;
      this.pxMax[0]   = this.pdivWidth - this.pxWidth
      this.ImgElements[0].styleleft = this.pxMin[0] + "px";
      this.ImgElements[0].style.width = this.pxWidth[0] + "px";
      // this.OnChangeCB(false, this.Value[0]);
      addEvent(this.ImgElements[0], 'mousedown', sliderMouseDown);
      break;
    case 2:
      this.IsDual = true;
      this.pxWidth[0] = 14;  // HARD-WIRED
      this.pxWidth[1] = 14;  // HARD-WIRED
      this.Value[0]   = this.Min;
      this.pxMin[0]   = 0;
      this.pxMax[0]   = this.pdivWidth - this.pxWidth[0] - this.pxWidth[1];
      this.ImgElements[0].style.left = this.pxMin[0] + "px";
      this.ImgElements[0].style.width = this.pxWidth[0] + "px";
      this.Value[1]   = this.Max;
      this.pxMin[1]   = this.pxWidth[0];
      this.pxMax[1]   = this.pdivWidth - this.pxWidth[1];
      this.ImgElements[1].style.left = this.pxMax[1] + "px";
      this.ImgElements[1].style.width = this.pxWidth[1] + "px";
      // this.OnChangeCB(false, this.Value[0], this.Value[1]);
      addEvent(this.ImgElements[0], 'mousedown', sliderMouseDown);
      addEvent(this.ImgElements[1], 'mousedown', sliderMouseDown);
      break;
    default:
      break;
    }
    el.vhslider = this;
}

/*
 * Update min/max
 *
 */
function updateVHSlider (min, max) {
    var el = document.getElementById("slider01");
    var slider = el.vhslider;
	var imgs = el.getElementsByTagName('img');
    slider.Value[0]    = min+'';
    slider.Value[1]    = max+'';
    switch (imgs.length) {
    case 1:
      if ( ! isNaN(min) ) {
          if (min < slider.Min) pct = 0;
          else if (min > slider.Max) pct = 1.0;
          else pct = (min - slider.Min) / (slider.Max - slider.Min);
          pxmin = Math.round( slider.pxMin[0] + ( pct * ( slider.pxMax[0] - slider.pxMin[0] ) ) );
          imgs[0].style.left = pxmin + "px";
      }
      break;
    case 2:
      if ( ! isNaN(min) ) {
          if (min < slider.Min) pct = 0;
          else if (min > slider.Max) pct = 1.0;
          else pct = (min - slider.Min) / (slider.Max - slider.Min);
          pxmin = Math.round( slider.pxMin[0] + ( pct * ( slider.pxMax[0] - slider.pxMin[0] ) ) );
          imgs[0].style.left = pxmin + "px";
      }
      if ( ! isNaN(max) ) {
          if (max < slider.Min) pct = 0.0;
          else if (max > slider.Max) pct = 1.0;
          else pct = (max - slider.Min) / (slider.Max - slider.Min);
          pxmax = Math.round( slider.pxMin[1] + ( pct * ( slider.pxMax[1] - slider.pxMin[1] ) ) );
          imgs[1].style.left = pxmax + "px";
      }
      break;
    default:
      break;
    }
}

function sliderMouseDown(e) {
    var pdiv = e.srcElement.parentNode
    var slider = pdiv.vhslider;
    switch (slider.ImgElements.length) {
    case 1:
      if (e.srcElement == slider.ImgElements[0])
      {
        activePDiv = pdiv;
        activeControlIdx = 0;
        activeLeft = null;
        activeClientX = null;
        addEvent(document, 'mouseup', sliderMouseUp);
        addEvent(document, 'mousemove', sliderMouseMove);
        stopEvent(e);
      }
      break;
    case 2:
      if (e.srcElement == slider.ImgElements[0])
      {
        activePDiv = pdiv;
        activeControlIdx = 0;
        activeLeft = null;
        activeClientX = null;
        addEvent(document, 'mouseup', sliderMouseUp);
        addEvent(document, 'mousemove', sliderMouseMove);
        stopEvent(e);
      }
      else if (e.srcElement == slider.ImgElements[1])
      {
        activePDiv = pdiv;
        activeControlIdx = 1;
        activeLeft = null;
        activeClientX = null;
        addEvent(document, 'mouseup', sliderMouseUp);
        addEvent(document, 'mousemove', sliderMouseMove);
        stopEvent(e);
      }
      break;
    default:
      break;
    }
}

function removePX(str) {
    if (str.length > 2) {
        str = str.substr(0, str.length-2);
    }
    return str;
}

function sliderMouseMove(e) {
    if (activePDiv != null)
    {
        var slider = activePDiv.vhslider;
        var activeControl = activePDiv.vhslider.ImgElements[activeControlIdx];
        var left = removePX(activeControl.style.left);
        if (left.length > 0)
        {
            // first time through, save e.clientX
            if (activeLeft == null) {
                activeLeft = parseInt(left);
                activeClientX = e.clientX;
            }
            // figure deltaX movement and move Image by that amount
            else {
                var deltaX = activeClientX - e.clientX;
                var newLeft = parseInt(left) - deltaX;
                if (newLeft < slider.pxMin[activeControlIdx]) newLeft = slider.pxMin[activeControlIdx];
                else if (newLeft > slider.pxMax[activeControlIdx]) newLeft = slider.pxMax[activeControlIdx];
                if (newLeft != activeLeft) {
                    // There is movement ...
                    activeClientX = e.clientX;
                    activeControl.style.left = newLeft + "px";
                    activeLeft = newLeft;
                    // Now with newLeft determined, see if we should alter the other (inactive) control
                    if (slider.IsDual) {
                        var inactiveControl = activePDiv.vhslider.ImgElements[1-activeControlIdx];
                        var inactiveLeft    = removePX(inactiveControl.style.left);
                        if ((activeControlIdx == 0) && (newLeft+slider.pxWidth[0] > inactiveLeft)) {
                            inactiveControl.style.left = newLeft+slider.pxWidth[0] + "px";
                        } else if ((activeControlIdx == 1) && (inactiveLeft > newLeft-slider.pxWidth[0])) {
                            inactiveControl.style.left = newLeft-slider.pxWidth[0] + "px";
                        }
                        // get both values and execute callback
                        var left1    = removePX(slider.ImgElements[0].style.left);
                        var left2    = removePX(slider.ImgElements[1].style.left);
                        var pct1     = ( left1 - slider.pxMin[0] ) / ( slider.pxMax[0] - slider.pxMin[0] );
                        var pct2     = ( left2 - slider.pxMin[1] ) / ( slider.pxMax[1] - slider.pxMin[1] );
                        var pval1    = slider.Min + ( pct1 * ( slider.Max - slider.Min ) );
                        var pval2    = slider.Min + ( pct2 * ( slider.Max - slider.Min ) );
                        pval1 = Math.round( pval1 / slider.Prec ) * slider.Prec;
                        pval2 = Math.round( pval2 / slider.Prec ) * slider.Prec;
                        slider.Value[0] = pval1+'';
                        slider.Value[1] = pval2+'';
                        slider.OnChangeCB(false, slider.Value[0], slider.Value[1]);
                    } else {
                        // get value and execute callback
                        var left1    = removePX(slider.ImgElements[0].style.left);
                        var pct1     = ( left1 - slider.pxMin[0] ) / ( slider.pxMax[0] - slider.pxMin[0] );
                        var pval1    = slider.Min + ( pct1 * ( slider.Max - slider.Min ) );
                        pval1 = Math.round( pval1 / slider.Prec ) * slider.Prec;
                        slider.Value[0] = pval1+'';
                        slider.OnChangeCB(false, slider.Value[0]);
                    }
                }
            }
        }
        stopEvent(e);
    }
}

function sliderMouseUp(e) {
    if (activePDiv != null)
    {
        var slider = activePDiv.vhslider;
        if (slider.IsDual)
            slider.OnChangeCB(true, slider.Value[0], slider.Value[1]);
        else
            slider.OnChangeCB(true, slider.Value[0]);
        removeEvent(document, 'mouseup', sliderMouseUp);
        removeEvent(document, 'mousemove', sliderMouseMove);
        activePDiv = null;
        activeControlIdx = null;
        activeLeft = null;
        activeClientX = null;
        stopEvent(e);
    }
}

function removeEvent(el, evname, func)
{
    if (el.detachEvent) { // IE
        el.detachEvent("on" + evname, func);
    } else if (el.removeEventListener) { // Gecko / W3C
        el.removeEventListener(evname, func, true);
    } else {
        el["on" + evname] = null;
    }
}

function addEvent(el, evname, func) {
    if (el.attachEvent) { // IE
        el.attachEvent("on" + evname, func);
    } else if (el.addEventListener) { // Gecko / W3C
        el.addEventListener(evname, func, true);
    } else {
        el["on" + evname] = func;
    }
}

function stopEvent(e) {
	if (e.preventDefault) {
		e.preventDefault();
		e.stopPropagation();
	} else {
		e.returnValue=false;
		e.cancelBubble=true;
	}
}

