var doc = window.document;

    function Dragable() {    	this.navObj = null;
    	this.pParent = null; // äîëæåí áûòü OnSliderPosition(sEvent = "drag", oPoint)
    	this.pmStart = {"x":0, "y":0}
    	this.poStart = {"x":0, "y":0}
    	this.bDragging = false;
    	this.mRange = {"cx": 0, "cy": 0, "step": 0, "sx": 0, "sy": 0}

		this.Create = function(id) {			var oDiv = he(id);
            if(oDiv == null) {
            	oDiv = doc.createElement("div");
                oDiv.id = id;
				oDiv.style.position = "absolute";
				doc.body.appendChild(oDiv);
			}

			this.Attach(id);		}
    	this.SetPosition = function(x, y) {
    		if(this.navObj != null) {
				if(this.mRange.cx || this.mRange.cy) {
     				if(x < this.mRange.sx) x = this.mRange.sx;
     				if(x > this.mRange.sx + this.mRange.cx) x = this.mRange.sx + this.mRange.cx;
     				if(y < this.mRange.sy) y = this.mRange.sy;
     				if(y > this.mRange.sy + this.mRange.cy) y = this.mRange.sy + this.mRange.cy;

     				if(this.mRange.steps) {
     					var ixStep = this.mRange.cx / this.mRange.steps;
     					var iyStep = this.mRange.cy / this.mRange.steps;

     					x = ixStep ? (this.mRange.sx + parseInt((x - this.mRange.sx + 1) / ixStep) * ixStep) : x;
     					y = iyStep ? (this.mRange.sy + parseInt((y - this.mRange.sy + 1) / iyStep) * iyStep) : y;
     				}
				}
        		this.navObj.style.top = y + "px";
        		this.navObj.style.left = x + "px";

        		return {"x":x, "y":y}
        	}

        	return false;    	}
    	this.Attach = function(id) {        	var o = he(id);
        	if((typeof(o) != "undefined") && (o != null)) {
                o.o = this;
        		this.navObj = o;
                var md = function(e) { return o.o.Catch(e); }
        		addEventHandler(o, "mousedown", md);
        	}    	}
    	this.Catch = function(e) {
    		if(this.bDragging == false) {
    			var e = e || window.event;
    			e.returnValue = false

		    	if (e.preventDefault) {
		        	e.preventDefault()
		    	}
                this.bDragging = true;

    			var pos = mousePageXY(e);
	    		this.pmStart.x = pos.x;
	    		this.pmStart.y = pos.y;

	    		pos = getElementPosition(this.navObj);
	    		this.poStart.x = pos.left;
	    		this.poStart.y = pos.top;

				var o = this.navObj;
                var mm = function(e) { return o.o.Drag(e); }
                var mu = function(e) {
                			removeEventHandler(doc, "mousemove", mm);
                			removeEventHandler(doc, "mouseup", mu);
                			return o.o.Drop(e);
                }
				addEventHandler(doc, "mousemove", mm);
        		addEventHandler(doc, "mouseup", mu);

	    		return true;
    		}
            return false;    	}
    	this.Drag = function(e) {    		if(this.bDragging == true) {
    			var e = e || window.event;
    			e.returnValue = false

		    	if (e.preventDefault) {
		        	e.preventDefault()
		    	}
	        	var pos = mousePageXY(e);

	        	var x = pos.x - (this.pmStart.x-this.poStart.x);
	        	var y = pos.y - (this.pmStart.y-this.poStart.y);

	         	this.SetPosition(x, y);
	         	if(this.pParent != null &&
	         		typeof(this.pParent.OnSliderPosition) == "function")
	        	{	        		this.pParent.OnSliderPosition("drag", {"offsetX": x-this.mRange.sx, "offsetY": y-this.mRange.sy});	        	}

				if(typeof(doc.selection) != "undefined")
					doc.selection.empty();
	    		return true;
    		}

            return false;    	}
    	this.Drop = function(e) {    		if(this.bDragging == true) {
    			var e = e || window.event;    			this.bDragging = false;
	         	if(this.pParent != null &&
	         		typeof(this.pParent.OnSliderPosition) == "function")
	        	{
	        		var pos = mousePageXY(e);

	        		var x = pos.x - (this.pmStart.x-this.poStart.x);
	        		var y = pos.y - (this.pmStart.y-this.poStart.y);
	        		this.pParent.OnSliderPosition("drop", {"offsetX": x-this.mRange.sx, "offsetY": y-this.mRange.sy});
	        	}
    			return true;    		}

    		return false;    	}
    	this.SetRange = function(rect, sp) {    		this.mRange.cx = rect.cx;
    		this.mRange.cy = rect.cy;
    		this.mRange.steps = sp;

			if(rect.x != -1 && rect.y != -1) {    			this.mRange.sx = rect.x;
            	this.mRange.sy = rect.y;			} else {
    			var pos = getElementPosition(this.navObj);
    			this.mRange.sx = pos.left;
            	this.mRange.sy = pos.top;
            }    	}    }
    function Slider(w, h, sw, sh, v, texts) {
    	this.oPosition = {"x": 0, "y": 0}
    	this.oSlideOffset = {"ox": 0, "oy": 0, "length": 0}    	this.oDimen = {"width": w, "height": h}
    	this.oSlDimen = {"width": sw, "height": sh}
        this.navObj = null;
        this.navTxtObj = null;
        this.dgo = null;
        this.vert = v; // true - âåðòèêàëüíîå, false - ãîðèçîíòàëüíîå
        this.texts = texts;
        if(typeof(this.texts) != 'object')
        	this.texts = new Array;
        else if(texts.length == 0)
        	this.texts[0] = "&nbsp;";

        this.Create = function(id, parentId) {
			var oDiv = he(id);
			var pDiv = he(parentId) || doc.body;

            if(oDiv == null) {
            	oDiv = doc.createElement("div");
                oDiv.id = id;
				oDiv.style.width = this.oDimen.width + "px";
				oDiv.style.height = this.oDimen.height + "px";
				pDiv.appendChild(oDiv);

				var tDiv = doc.createElement("div");
				tDiv.id = "tx__" + id;
				tDiv.innerHTML = this.texts[0];
				pDiv.appendChild(tDiv);
			} else {				alert("Ýëåìåíò ñ id = " + id + " óæå ñóùåñòâóåò");
				return false;			}

			var o = he(id);
            o.o = this;
            this.navObj = o;
         	this.navTxtObj = he("tx__" + id);
         	this.navTxtObj.o = this;

			var pos = getElementPosition(this.navObj);
			this.oPosition.x = pos.left;
			this.oPosition.y = pos.top;

         	this.dgo = new Dragable();
         	this.dgo.Create("sl__" + id);
         	this.dgo.navObj.style.width = this.oSlDimen.width + "px";
			this.dgo.navObj.style.height = this.oSlDimen.height + "px";
         	this.dgo.pParent = this;
			this.SetSlidePosition();

            addEventHandler(window, "resize", function(e) {	return o.o.UpdateSlidePosition(e); } );
            addEventHandler(o, "click", function(e) { return o.o.OnClick(e); } );
			return true;        }
        this.OnClick = function(e) {        	var pos = mousePageXY(e);
        	pos.x = this.vert ? pos.x : (pos.x-parseInt(this.oSlDimen.width/2));
        	pos.y = this.vert ? (pos.y-parseInt(this.oSlDimen.height/2)) : pos.y;

            var oPoint = this.dgo.SetPosition(pos.x, pos.y);
        	this.OnSliderPosition("set", {"offsetX": oPoint.x-this.dgo.mRange.sx, "offsetY": oPoint.y-this.dgo.mRange.sy});        }
        this.OnSliderPosition = function(sEvent, oPoint) {        	var index = this.vert ? parseInt((oPoint.offsetY)/this.oSlideOffset.length*(this.texts.length-1)) :
        							parseInt((oPoint.offsetX)/this.oSlideOffset.length*(this.texts.length-1));
        	if(index < 0) index = 0;
        	else if(index >= this.texts.length) index = this.texts.length-1;

        	this.navTxtObj.innerHTML = this.texts[index];        }
        this.SetSliderOffset = function(oPoint, nLen) {        	nLen = typeof(nLen) == "undefined" ? this.vert ? this.oDimen.height : this.oDimen.width : nLen;
         	oPoint = typeof(oPoint) == "undefined" ? this.vert ?
         				{"ox": this.oDimen.width, "oy": 0} : {"ox": 0, "oy": this.oDimen.height} : oPoint;

            this.oSlideOffset.ox = oPoint.ox;
            this.oSlideOffset.oy = oPoint.oy;
            this.oSlideOffset.length = nLen;        }
        this.SetSlidePosition = function() {        	var x=0, y=0;
        	if(this.vert) {
               	x = this.oPosition.x + this.oSlideOffset.ox;
               	y = this.oPosition.y;
            } else {               	x = this.oPosition.x;
               	y = this.oPosition.y + this.oSlideOffset.oy;
        	}

        	this.dgo.SetPosition(x, y);
        	this.dgo.SetRange({"x":-1, "y":-1, "cx": (this.vert ? 0 : this.oSlideOffset.length),
        										"cy": (this.vert ? this.oSlideOffset.length : 0)}, 0);        }
        this.UpdateSlidePosition = function(e) { 			var pos = getElementPosition(this.navObj);
			var x = pos.left - this.oPosition.x;
            var y = pos.top - this.oPosition.y;

			this.oPosition.x = pos.left;
			this.oPosition.y = pos.top;

   			pos = getElementPosition(this.dgo.navObj);
            x += pos.left;
            y += pos.top;

		this.dgo.SetRange({"x":this.oPosition.x+this.oSlideOffset.ox, "y":this.oPosition.y+this.oSlideOffset.oy,
            				   "cx": (this.vert ? 0 : this.oSlideOffset.length),
        					   "cy": (this.vert ? this.oSlideOffset.length : 0)}, 0
        					 );
            this.dgo.SetPosition(x, y);
            }    }
