/********************************************************
*	Creates a JS Slider Object
*
*	@author      Ava Hristova
*	@version     1.00
*	@copyright   Yahoo! Inc
********************************************************/

var yg_slider_timerID = 0;

var yg_slider_full = 0;
var yg_slider_supported = 0;
if (oBw.dom) { 
    if (oBw.mac) { // macs get the radios for now
        yg_slider_supported = 1;
    }
    else if (oBw.ie5) { 
        yg_slider_supported = 1;
        yg_slider_full = 1;
        if (oBw.agt.indexOf('msie 5.0') > 0) {
            yg_slider_full = 0;
        }
    } 
    else {
        yg_slider_supported = 1;
    } 
}

// slider object constructor
function slider(objName, sliderDir, 
                fdrOnImg, fdrOffImg, fdrImgWidth, fdrImgHeight, 
                trackImg, trackImgWidth, trackImgHeight, 
                numTicks, 
                onChange, onChangeDelay,
                labels, containerForm){
	this.objName			= objName;										
	this.faderImgOn			= new Image(); this.faderImgOn.src 	= fdrOnImg;	
	this.faderImgOff		= new Image(); this.faderImgOff.src	= fdrOffImg;
	this.trackImg			= new Image(); this.trackImg.src 	= trackImg;	
	this.direction			= sliderDir;									
	this.tickNum			= numTicks;										
    this.onChange           = onChange;                                     
    this.onChangeDelay      = onChangeDelay || 250;                         
    this.labels             = labels;
	this.containerForm = containerForm;									
	this.maxLimit;
	this.faderDirDim;
	this.tickDistance;
	this.selectedObj;
	this.curFaderPos;
	this.parentDivNode;									
	
	
	/********************************************************
	*	function: dragFader()
	*	tracks the fader element along mouse movement
	*	parameters: mouse event
	********************************************************/
	this.dragFader = function(evt) {
		var thisOffset;
		
		// determine if a fader element is the calling object
		if (this.selectedObj) {
            // move along the horizontal axis
            if (yg_slider_full) { 
                this.selectedObj.pixelLeft = this.getNextFaderPosition(
                    (window.event.clientX + document.body.scrollLeft - this.parentDivNode.offsetLeft - (imgObj.width/2)), imgObj.width);
            }
            if (this.labels) {
                this.updateLabel();
            }
            if (this.onChange) {
                  if (yg_slider_timerID) {
                      clearTimeout(yg_slider_timerID);
                  }
                  yg_slider_timerID = setTimeout(this.onChange, this.onChangeDelay);
            }
		}
	}
	
	/********************************************************
	*	function: drawSliderOjb()
	*	renders the slider object on the screen
	*	parameters: none
	********************************************************/
	this.drawSliderOjb = function() {
		var sdrTop, trkTop, trkLeft, elWidth, elHeight;
		var writeStr = "";

        if (yg_slider_full) {
            sdrTop = 0;
            trkTop = (this.faderImgOff.width - this.trackImg.height)/2;
            trkLeft = 0;
            elWidth = this.trackImg.width;
            elHeight = this.faderImgOff.width;
            
            writeStr = writeStr + "<div id=\"" + this.objName + "\" onmousedown=\"javascript:startFaderMovement(event);\" onmouseup=\"javascript:endFaderMovement(event);\" style=\"position: relative; width: " + elWidth + "px; height: " + elHeight + "px;\">\n";
            writeStr = writeStr + "	<div id=\"" + this.objName + "_fdrLr\" style=\"position: absolute; top:" + sdrTop + "; left: 0; z-index:1;\"><img id=\"" + this.objName + "_fdr\" src=\"" + this.faderImgOff.src + "\" alt=\"\" border=\"0\"></div>\n";
            writeStr = writeStr + "	<div id=\"" + this.objName + "_trkLr\" style=\"position: absolute; top:" + trkTop + "; left:" + trkLeft + "; z-index:0;\"><img id=\"" + this.objName + "_trk\" src=\"" + this.trackImg.src + "\" alt=\"\" border=\"0\"></div>\n";
            writeStr = writeStr + "<span style='padding-left: 125px;' id='" + this.objName + "_label'></span></div>";
        } else { // downgraded behavior
            var n = this.objName + '_radio';
            writeStr += '<table cellpadding="0" cellspacing="0" border="0"><tr>';
            var emit_form = 0;
            if (this.containerForm == undefined) {
                this.containerForm = this.objName + '_form';
                emit_form = 1;
                writeStr += '<form name="' + this.objName + '_form">';
            } 
            writeStr += '<td>';

            for (var i = 0; i < 5; i++) {
                id = n + i;
                if (i == 0) {
                    writeStr += '<input checked onclick="radioClick(this);" type="radio" value="' + i + '" name="' + n + '" id="' + id + '">';
                } else {
                    writeStr += '<input onclick="radioClick(this);" type="radio" value="' + i + '" name="' + n + '" id="' + id + '">';
                }
            }
            writeStr = writeStr + "</td><td><span id='" + this.objName + "_label'></span></td>";
            if (emit_form) {
                writeStr += '</form>';
            }
            writeStr += '</tr></table>';
        }

		document.write(writeStr);
	}

    this.updateLabel = function() {
        var percent = this.getPercent();
        var pos  = percent * (this.labels.length-1) / 100;
        if (pos == 0) { 
        } else {
            pos = Math.floor(pos)?Math.floor(pos):1;
        }
        document.getElementById(this.objName + "_label").innerHTML = this.labels[pos].l;
    }
	
	/********************************************************
	*	function: endFaderDrag()
	*	ends movement of the fader element
	*	parameters: none
	********************************************************/
	this.endFaderDrag = function() {
		this.swapFaderImg(0);		// swap out the fader graphic to an "off" state
        if (this.onChange) {
              if (yg_slider_timerID) {
                  clearTimeout(yg_slider_timerID);
              }
              yg_slider_timerID = setTimeout(this.onChange, 10);
        }
	}
	
	/********************************************************
	*	function: getNextSkipPosition()
	*	returns the position of the next tick element on the track
	*	parameters:	obj - the current fader location, 
	*				thisDir - the direction along the track the fader will be moving
	********************************************************/
	this.getNextSkipPosition = function(objLoc, thisDir) {
		if (thisDir == "up") {
			this.curFaderPos = Math.ceil(objLoc / this.tickDistance) * this.tickDistance;
			this.curFaderPos = this.curFaderPos - this.tickDistance;
			if (this.curFaderPos < 0) {
				this.curFaderPos = 0;
			}
		} else {
			this.curFaderPos = Math.floor(objLoc / Math.floor(this.tickDistance)) * this.tickDistance;
			this.curFaderPos = this.curFaderPos + this.tickDistance;
			if (this.curFaderPos > (this.maxLimit - this.faderDirDim)) {
				this.curFaderPos = this.maxLimit - this.faderDirDim;
			}
		}
		
		return this.curFaderPos;
	}
	
	/********************************************************
	*	function: getNextFaderPosition()
	*	returns the new position the fader element
	*	parameters:	curMousePos - the current mouse position, 
	*				objDim - the horizontal or vertical dimension of the fader
	********************************************************/
	this.getNextFaderPosition = function(curMousePos, objDim) {
		var newLoc;
		
		if (curMousePos < 0) {
			// motion has moved past the min limit, so stay
			newLoc = 0;
		} else if (curMousePos > (this.maxLimit - objDim)) {
			// motion has moved past the max limit, so stay
			newLoc = this.maxLimit - objDim;
		} else {
			// motion is within range, so can move freely
			newLoc = curMousePos;
		}
		return newLoc;
	}
	
	/********************************************************
	*	function: getPosition()
	*	returns the current pixel position of the slider
	*	parameters:	evt - mouse event
	********************************************************/
	this.getPosition = function(evt) {
		var curPos = 0;
		
        if (yg_slider_full) { // IE
            curPos = parseInt(this.selectedObj.pixelLeft);
        } else if (yg_slider_supported) { // downgraded
            var radios = this._getRadios();
            var len = radios.length;
            for (var i = 0; i < len; i++) {
                var r = radios[i];
                if (r.checked) { curPos = Math.floor(i * this.maxLimit / (len - 1)); break }
            }
        }
		
        return curPos;
	}
    
    this._getRadios = function() {
        var result = document.forms[this.containerForm][this.objName + '_radio'];
        return result;
    }

	/********************************************************
	*	function: getPercent()
	*	returns the current percent position of the slider
	*	parameters:	evt - mouse event
	********************************************************/
    this.getPercent = function(evt) {
        // get current position
        var curPos = this.getPosition(evt);
		// calculate the percentage progress of the fader and display in status bar
		return Math.round(100 * (curPos/(this.maxLimit - this.faderDirDim)));
    }

    this.setPosition = function(pos) {
        if (yg_slider_full) {
            this.selectedObj.pixelLeft = this.getNextFaderPosition(pos, 10);
        } else if (yg_slider_supported) { // downgraded
            var radios = this._getRadios();
            var len = radios.length;
            var index = Math.floor((len * pos) / this.maxLimit);
            if (index >= len) { index = len - 1; }
            if (index < 0) { index = 0; }
            radios[index].checked = true;
        }
        if (this.labels) {
            this.updateLabel();
        }
    }

    this.setPercent = function(perc) {
        var pos = Math.round((perc * (this.maxLimit - this.faderDirDim)) / 100);
        this.setPosition(pos);
    }
	
	/********************************************************
	*	function: initSliderObj()
	*	initialized the slider object, elements and properties
	*	parameters: none
	********************************************************/
	this.initSliderObj = function() {
		// get the dimesions of the fader and track elements
		this.faderImgOn.width = this.faderImgOff.width = fdrImgWidth;
		this.faderImgOn.height = this.faderImgOff.height = fdrImgHeight;
		this.trackImg.width = trackImgWidth;
		this.trackImg.height = trackImgHeight;
		
		// calculate the track jump distance
        if (yg_slider_full) {
            this.faderDirDim = this.faderImgOff.height;
        } else {
            this.faderDirDim = 0;
        }
        this.maxLimit = this.trackImg.width;
        this.curFaderPos = 0;
		this.tickDistance = (this.maxLimit - this.faderDirDim)/this.tickNum;
		
		// draw the slider object
		this.drawSliderOjb();
		
		// for the movement of the fader element get the fader object itself 
		var tempFdrObj;
		tempFdrObj = document.getElementById(this.objName + "_fdr");
		if (yg_slider_full) {
			this.selectedObj = tempFdrObj.parentElement.style;
            this.parentDivNode = tempFdrObj.parentNode.parentNode;
		}
		
	}
	
	/********************************************************
	*	function: skipSlider()
	*	shifts the fader elements along the track element
	*	parameters: mouse event
	********************************************************/
	this.skipSlider = function(evt) {
		var thisOffset;
	
		// determine if a track element is the calling object
		if (this.selectedObj) {
            // move along the horizontal axis
            if (yg_slider_full) { // IE
                thisOffset = this.parentDivNode.offsetLeft + document.body.scrollLeft;
                if ((window.event.clientX - thisOffset) < this.selectedObj.pixelLeft) {
                    this.selectedObj.pixelLeft = this.getNextSkipPosition(this.selectedObj.pixelLeft, "up");
                } else {
                    this.selectedObj.pixelLeft = this.getNextSkipPosition(this.selectedObj.pixelLeft, "down");
                }
            }
            if (this.labels) {
                this.updateLabel();
            }
            if (this.onChange) {
                  if (yg_slider_timerID) {
                      clearTimeout(yg_slider_timerID);
                  }
                  yg_slider_timerID = setTimeout(this.onChange, 10);
            }
        }
    }
	
	/********************************************************
	*	function: startFaderDrag()
	*	begins the drag movement of the fader element
	*	parameters: mouse event
	********************************************************/
	this.startFaderDrag = function(evt) {
		this.swapFaderImg(1);		// swap out the fader graphic to an "on" state
	}
	
	/********************************************************
	*	function: swapFaderImg()
	*	swaps out the fader element graphic
	*	parameters: flag - current state;
	********************************************************/
	this.swapFaderImg = function(flag) {
		var thisObj, thisSrc;
		
		if (flag == 1) {
			thisSrc = this.faderImgOn.src;
		} else {
			thisSrc = this.faderImgOff.src;
		}
		
		thisObj = document.getElementById(this.objName + "_fdr");
		thisObj.src = thisSrc;
	}
}

var imgObj, callingSlider;
/********************************************************
*	function: dragFader()
*	signals a drag movement
*	parameters:	evt - mouse event
********************************************************/
function dragFader(evt) {
	// call object drag method if a fader element is the calling parent
	if (callingSlider && (imgObj.id.indexOf("_fdr") > 0)) {
		callingSlider.dragFader(evt);
	} else {
		// release event to browser default (allowing text selection, etc.)
		if (yg_slider_full) {
			document.ondragstart = function() { return false; }
		}
	}
	return false;
}

/********************************************************
*	function: endFaderMovement()
*	signals the end of mouse movement
*	parameters:	evt - mouse event
********************************************************/
function endFaderMovement(evt) {
	// dealocate memory and disasociate elements
	if (callingSlider && callingSlider.endFaderDrag) {
		callingSlider.endFaderDrag();
		callingSlider = null;
	}
	return false;
}

/********************************************************
*	function: getCallingObject()
*	returns the object whic requested an action
*	parameters:	evt - mouse event
********************************************************/
function getCallingObject(evt) {
	if (yg_slider_full) {
		imgObj = window.event.srcElement;
	}
}

/********************************************************
*	function: getCallingSlider()
*	returns the slider element requesting an action
*	parameters:	none
********************************************************/
function getCallingSlider() {
	var suffix, thisObjName, thisObj;
	
	if (imgObj.id.indexOf("_fdr") > 0) {
		suffix = "_fdr";
	} else if (imgObj.id.indexOf("_trk") > 0) {
		suffix = "_trk";
	} else if (imgObj.id.indexOf("_radio") > 0) {
		suffix = "_radio";
	} else {
		suffix = "";
	}

    var offset = imgObj.id.indexOf(suffix);
	
	thisObjName = imgObj.id.substring(0, offset);
	thisObj = eval(thisObjName);
	
	return thisObj;
}

function radioClick(r) {
    imgObj = r;
    var callingRadio = getCallingSlider();
    if (callingRadio) {
            if (callingRadio.labels) {
                callingRadio.updateLabel();
            }
            if (callingRadio.onChange) {
                  if (yg_slider_timerID) {
                      clearTimeout(yg_slider_timerID);
                  }
                  yg_slider_timerID = setTimeout(callingRadio.onChange, callingRadio.onChangeDelay);
            }
    }
}

/********************************************************
*	function: startFaderMovement()
*	signals the start of mouse movement
*	parameters:	evt - mouse event
********************************************************/
function startFaderMovement(evt) {
	// get the image object the called for the action
	getCallingObject(evt);
	
	// if that object exists
	if (imgObj) {
		// determine which element called for it (fader or track)
		callingSlider = getCallingSlider();
		if (callingSlider && (imgObj.id.indexOf("_fdr") > 0)) {
			// drag fader element along track
			callingSlider.startFaderDrag(evt);
		} else if (callingSlider && (imgObj.id.indexOf("_trk") > 0)) {
			// shift up fader along track ticks
			callingSlider.skipSlider(evt);
		}
	}
	return false;
}
