function IMS2_Zoombar(mapid,id,type){
    var self = this;
    
    this.mapid = mapid;
    this.id = id;
    this.type = type;
    this.downx = -1;
    this.downy = -1;
    this.orgpos = -1;
    this.isDragging = false;
    this.ZoomScales;
    this.ZoomScaleLabels;
    
    function Init(){
        if("Input" == self.type){
            var goButton = document.getElementById("_zoombar_" + self.id + "_go");
            if(goButton){
                IMS2_AttachEvent(goButton,"click",self.GoButtonClick);
            }
            var inputBox = document.getElementById("_zoombar_" + self.id + "_tinput");
            if(inputBox){
                IMS2_AttachEvent(inputBox,"keypress",self.InputKeyPress);
            }
        }
        else if("Slider" == self.type){
            var sliderDiv = document.getElementById("_zoombar_" + self.id);
            var sliderHandleDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandle");
            var sliderHandleTipDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandleTip");
            if(sliderDiv){
                sliderDiv.unselectable = "on";
                if(sliderDiv.addEventListener){
                    sliderDiv.addEventListener("resize",self._SliderResize,false);
                }else if(sliderDiv.attachEvent){
                    sliderDiv.attachEvent("onresize",self._SliderResize);
                }else{
                    sliderDiv.onresize = _SliderResize;
                }
            }
            if(sliderHandleDiv){
                sliderHandleDiv.unselectable = "on";
                sliderHandleDiv.onmousedown = _SliderBeginDrag;
            }
            if(sliderHandleTipDiv){
                sliderHandleTipDiv.unselectable = "on";
            }
        }
        else if("Fixed" == self.type)
        {
			//window.status = "hello";
        }
    }
    this.Init = Init;
    
    function _SliderResize(){
        if(false == self.isDragging){
            var mapctl = ((IMS2_MapManager)?(IMS2_MapManager.GetMap(self.mapid)):(null));
            if(mapctl){
                self.Update(mapctl);
            }
        }
    }
    this._SliderResize = _SliderResize;
    
    function _SliderBeginDrag(e){
        if(!e){
            e = window.event;
        }
        if(e){
            self.downx = IMS2_GetMouseX(e);
            self.downy = IMS2_GetMouseY(e);
            self.isDragging = true;
            var sliderDiv = document.getElementById("_zoombar_" + self.id);
            var sliderHandleDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandle");
            var sliderHandleTipDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandleTip");
            if(sliderHandleDiv){
                self.orgpos = (sliderHandleDiv.style["left"])?(parseInt(sliderHandleDiv.style["left"])):(sliderHandleDiv.offsetLeft);
            }
            if(sliderHandleTipDiv){
                sliderHandleTipDiv.style["visibility"] = "visible";
                self._SliderSetTip(sliderHandleTipDiv,sliderHandleDiv,sliderDiv);
            }
            if(document.addEventListener){
                document.addEventListener("mouseup",self._SliderEndDrag,true);
                document.addEventListener("mousemove",self._SliderDrag,true);
            }else if(document.attachEvent){
                document.attachEvent("onmouseup",self._SliderEndDrag);
                document.attachEvent("onmousemove",self._SliderDrag);
            }
        }
    }
    this._SliderBeginDrag = _SliderBeginDrag;
    
    function _SliderSetTip(sliderHandleTipDiv,sliderHandleDiv,sliderDiv){
        /*
        var sliderHandleTipDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandleTip");
        var sliderHandleDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandle");
        var sliderDiv = document.getElementById("_zoombar_" + self.id);
        */
        if(sliderHandleTipDiv && sliderHandleDiv && sliderDiv){
            var handleWidth = sliderHandleDiv.offsetWidth;
            var maxPos = sliderDiv.offsetWidth - sliderHandleDiv.offsetWidth;
            var pos = (sliderHandleDiv.style["left"])?(parseInt(sliderHandleDiv.style["left"])):(sliderHandleDiv.offsetLeft);
            if(maxPos){
                var r = pos / maxPos;
                var tipPos = 0;
                var mapctl = ((IMS2_MapManager)?(IMS2_MapManager.GetMap(self.mapid)):(null));
                if(mapctl){
                    if(mapctl.maxscale && mapctl.minscale){
                        var scale = mapctl.minscale + (IMS2_ZoombarRatioUnskew(r) * (mapctl.maxscale - mapctl.minscale));
                        sliderHandleTipDiv.innerHTML = "" + Math.round(self._UnitPerPxToScale(mapctl,scale));
                        if(r > 0.5){
                            sliderHandleTipDiv.style["left"] = "0px";
                            sliderHandleTipDiv.style["width"] = pos + "px";
                            sliderHandleTipDiv.style["textAlign"] = "right";
                        }else{
                            tipPos = pos + sliderHandleDiv.offsetWidth;
                            sliderHandleTipDiv.style["left"] = tipPos + "px";
                            sliderHandleTipDiv.style["width"] = null;
                            sliderHandleTipDiv.style["textAlign"] = "left";
                        }
                    }
                }
            }
        }
    }
    this._SliderSetTip = _SliderSetTip;
    
    function _SliderDrag(e){
        if(!e){
            e = window.event;
        }
        if(e){
            var x = IMS2_GetMouseX(e);
            var y = IMS2_GetMouseY(e);
            var dx = x - self.downx;
            var cancelit = false;
            var sliderHandleDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandle");
            var sliderDiv = document.getElementById("_zoombar_" + self.id);
            if(sliderHandleDiv && sliderDiv){
                var sliderPos = IMS2_GetElementPosition(sliderDiv);
                var sliderSize = IMS2_GetElementDimension(sliderDiv);
                if(sliderPos && sliderSize){
                    if(IMS2_HasLeftBoundRange(y,sliderPos[1],sliderPos[1] + sliderSize[1],sliderSize[1]) || IMS2_HasLeftBoundRange(x,sliderPos[0],sliderPos[0] + sliderSize[0],sliderSize[1])){
                        cancelit = true;
                    }
                }
            }
            if(cancelit){
                self._CancelSlide();
            }else{
                var sliderHandleTipDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandleTip");
                self._MoveHandleTo(self.orgpos + dx);
                self._SliderSetTip(sliderHandleTipDiv,sliderHandleDiv,sliderDiv);
            }
        }
    }
    this._SliderDrag = _SliderDrag;
    
    function _MoveHandleToRatio(r){
        var sliderHandleDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandle");
        var sliderDiv = document.getElementById("_zoombar_" + self.id);
        if(sliderHandleDiv && sliderDiv){
            var maxPos = sliderDiv.offsetWidth - sliderHandleDiv.offsetWidth;
            var pos = maxPos * r;
            sliderHandleDiv.style["left"] = pos + "px";
        }
    }
    this._MoveHandleToRatio = _MoveHandleToRatio;
    
    function _MoveHandleTo(pos){
        var sliderHandleDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandle");
        var sliderDiv = document.getElementById("_zoombar_" + self.id);
        if(sliderHandleDiv && sliderDiv){
            var maxPos = sliderDiv.offsetWidth - sliderHandleDiv.offsetWidth;
            if(pos < 0){
                pos = 0;
            }else if(pos > maxPos){
                pos = maxPos;
            }
            sliderHandleDiv.style["left"] = pos + "px";
        }
    }
    this._MoveHandleTo = _MoveHandleTo;
    
    function _CancelSlide(){
        self._UnhookDocEvents();
        self.isDragging = false;
        var sliderHandleTipDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandleTip");
        if(sliderHandleTipDiv){
            sliderHandleTipDiv.style["visibility"] = "hidden";
        }
        var mapctl = ((IMS2_MapManager)?(IMS2_MapManager.GetMap(self.mapid)):(null));
        if(mapctl){
            self.Update(mapctl);
        }
    }
    this._CancelSlide = _CancelSlide;
    
    function _SliderEndDrag(e){
        if(!e){
            e = window.event;
        }
        if(e){
            self._UnhookDocEvents();
            self.isDragging = false;
            var sliderHandleDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandle");
            var sliderDiv = document.getElementById("_zoombar_" + self.id);
            var sliderHandleTipDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandleTip");
            if(sliderHandleTipDiv){
                sliderHandleTipDiv.style["visibility"] = "hidden";
            }
            if(sliderHandleDiv && sliderDiv){
                var dx = x - self.downx;
                var x = IMS2_GetMouseX(e);
                var y = IMS2_GetMouseY(e);
                var maxPos = sliderDiv.offsetWidth - sliderHandleDiv.offsetWidth;
                var pos = (sliderHandleDiv.style["left"])?(parseInt(sliderHandleDiv.style["left"])):(sliderHandleDiv.offsetLeft);
                if(maxPos && 0 != maxPos){
                    var ratio = pos/maxPos;
                    self._SetScaleScrollRatio(IMS2_ZoombarRatioUnskew(ratio));
                }
            }
        }
    }
    this._SliderEndDrag = _SliderEndDrag;
    
    function _UnhookDocEvents(){
        try{
            if(document.removeEventListener){
                document.removeEventListener("mouseup",self._SliderEndDrag,true);
                document.removeEventListener("mousemove",self._SliderDrag,true);
            }else if(document.detachEvent){
                document.detachEvent("onmouseup",self._SliderEndDrag);
                document.detachEvent("onmousemove",self._SliderDrag);
            }
        }catch(e){;}
    }
    this._UnhookDocEvents = _UnhookDocEvents;
    
    function InputKeyPress(e){
        if(!e){
            e = window.event;
        }
        if(e){
            if(13 == e.keyCode){
                self.GoButtonClick();
            }
        }
    }
    this.InputKeyPress = InputKeyPress;
    
    function GoButtonClick(){
        if(IMS2_MapManager){
            var inputBox = document.getElementById("_zoombar_" + self.id + "_tinput");
            if(inputBox){
                var val = 0;
                try{
                    val = parseFloat(inputBox.value);
                }catch(e){alert(e);}
                if(val && val != 0){
                    var mapctl = IMS2_MapManager.GetMap(self.mapid);
                    if(mapctl){
                        var unit = ((mapctl.unit && mapctl.unit != "")?(mapctl.unit):("meter"));
                        var scale = IMS2_ConvertValueLengthUnit(val,"pixel",unit); 
                        if(scale && scale != 0){
                            mapctl.ChangePxScale(scale);
                        }
                    }
                }
            }
        }
    }
    this.GoButtonClick = GoButtonClick;
    
    function ZoomScaleClick(val)
    {
		if(val && val != 0){
			var mapctl = IMS2_MapManager.GetMap(self.mapid);
			if(mapctl){
				var unit = ((mapctl.unit && mapctl.unit != "")?(mapctl.unit):("meter"));
				var scale = IMS2_ConvertValueLengthUnit(val,"pixel",unit); 
				if(scale && scale != 0){
					mapctl.ChangePxScale(scale);
				}
			}
		}
    }
    this.ZoomScaleClick = ZoomScaleClick;
    
    function TriggerResize(){
        if("Slider" == self.type){
            self._SliderResize();
        }
    }
    this.TriggerResize = TriggerResize;
    
    function Update(mapctl){
        if(mapctl){
            if("Input" == self.type){
                self._UpdateText(mapctl);
            }else if("Slider" == self.type){
                self._UpdateSlider(mapctl);
            }else if("MaxScale" == self.type){
                self._UpdateMax(mapctl);
            }
            else if("Fixed" == self.type){
                self._UpdateFixed(mapctl);
            }
        }
    }
    this.Update = Update;
    
    function _UpdateSlider(mapctl){
        var unitPerPx = mapctl.GetCurrentPxScale();
        var scale = unitPerPx;//self._UnitPerPxToScale(mapctl,unitPerPx);
        //var maxScale = mapctl.maxscale;//self._UnitPerPxToScale(mapctl,mapctl.maxscale);
        if(scale && mapctl.maxscale && mapctl.minscale){
            var scaleRange = (mapctl.maxscale-mapctl.minscale);
            if(scaleRange != 0){
                var ratio = (scale-mapctl.minscale) / scaleRange;
                if(ratio < 0){
                    ratio = 0;
                }else if(ratio > 1){
                    ratio = 1;
                }
                var srDiv = document.getElementById("_zoombar_" + self.id + "_sliderLayerRange");
                if(srDiv){
                    if(mapctl.layers){
                        var activeLayer = mapctl.layers.Get(mapctl.activeLayer);
                        if(activeLayer){
                            var minScale = activeLayer.minScale;
                            var maxScale = activeLayer.maxScale;
                            if(minScale < 0){
                                minScale = (mapctl.minscale)?(mapctl.minscale):(1);
                            }
                            if(maxScale < 0){
                                maxScale = (mapctl.maxscale)?(mapctl.maxscale):(minScale);
                            }
                            if((minScale == mapctl.minscale && maxScale == mapctl.maxscale) || minScale == maxScale){
                                srDiv.style["visibility"] = "hidden";
                            }else{
                                var left = IMS2_ZoombarRatioSkew(minScale / scaleRange);
                                var right = IMS2_ZoombarRatioSkew(maxScale / scaleRange);
                                var sliderHandleDiv = document.getElementById("_zoombar_" + self.id + "_sliderHandle");
                                var sliderDiv = document.getElementById("_zoombar_" + self.id);
                                if(sliderHandleDiv && sliderDiv){
                                    left *= (sliderDiv.offsetWidth - sliderHandleDiv.offsetWidth);
                                    right = sliderHandleDiv.offsetWidth + (right * (sliderDiv.offsetWidth - sliderHandleDiv.offsetWidth));
                                    if(IMS2_isMSIE()){
                                        left = left + 1;
                                        right = right - 1;
                                    }
                                    var width = right - left;
                                    if(width > 0){
                                        srDiv.style["visibility"] = "visible";
                                        srDiv.style["left"] = parseInt(left) + "px";
                                        srDiv.style["width"] = Math.round(width) + "px";
                                    }else{
                                        srDiv.style["visibility"] = "hidden";
                                    }
                                }
                            }
                        }else{
                            srDiv.style["visibility"] = "hidden";
                        }
                    }else{
                        srDiv.style["visibility"] = "hidden";
                    }
                }
                
                if(!self.isDragging){
                    self._MoveHandleToRatio(IMS2_ZoombarRatioSkew(ratio));
                }
            }
        }
    }
    this._UpdateSlider = _UpdateSlider;
    
    function _SetScaleScrollRatio(r){
        var mapctl = ((IMS2_MapManager)?(IMS2_MapManager.GetMap(self.mapid)):(null));
        if(mapctl){
            if(mapctl.maxscale){
                var scale = mapctl.minscale + (r * (mapctl.maxscale - mapctl.minscale));
                mapctl.ChangePxScale(scale);       
            }
        }
    }
    this._SetScaleScrollRatio = _SetScaleScrollRatio;
    
    function _UnitPerPxToScale(mapctl,unitPerPx){
        return(IMS2_ConvertValueLengthUnit((unitPerPx < 0) ? (0) : (unitPerPx),((mapctl.unit && mapctl.unit != "")?(mapctl.unit):("meter")),"pixel"));
    }
    this._UnitPerPxToScale = _UnitPerPxToScale;
    
    function _UpdateText(mapctl){
        var unitPerPx = mapctl.GetCurrentPxScale();
        var scale = self._UnitPerPxToScale(mapctl,unitPerPx);
        
        var inputBox = document.getElementById("_zoombar_" + self.id + "_tinput");
        if(inputBox){
            scale = Math.round(scale);
            inputBox.value = "" + ((scale && (scale != 0))?(scale):(""));
        }
    }
    this._UpdateText = _UpdateText;
    
    function _UpdateFixed(mapctl){
		
		for( var i = 0; i < this.ZoomScales.length; i++)
		{
			document.getElementById(self.id + "_FixedScale_" + i).className = "zoomFixedScale";
		}
		
		var unitPerPx = mapctl.GetCurrentPxScale();
        var scale = self._UnitPerPxToScale(mapctl,unitPerPx);
        scale = Math.round(scale);
        var index;        
        
        if(scale <= this.ZoomScales[0])
        {
			index = 0;
        }
        else if(scale >= this.ZoomScales[this.ZoomScales.length-1])
        {
			index = this.ZoomScales.length - 1;
        }
        else
        {
			for( var i = 1; i < this.ZoomScales.length; i++)
			{
				if(Math.abs(scale - this.ZoomScales[i]) < Math.abs(scale - this.ZoomScales[i - 1]))
				{
					index = i;
				}
				else
				{
					index = i - 1;
					break;
				}
			}
        }
        
        var td = document.getElementById(self.id + "_FixedScale_" + index);
        if(td){
			td.className = "zoomFixedScaleSelected";
        }
        
    }
    this._UpdateFixed = _UpdateFixed;
    
    function _UpdateMax(mapctl){
        var maxSpan = document.getElementById("_zoombar_" + self.id );
        if(maxSpan){
            var scale = self._UnitPerPxToScale(mapctl,mapctl.maxscale);
            scale = Math.round(scale);
            var maxStr = "" + scale;
            if(maxSpan.innerHTML != maxStr){
                maxSpan.innerHTML = maxStr;
            }
        }
    }
    this._UpdateMax = _UpdateMax;
}

function IMS2_ZoombarManager(){
    var self = this;
    
    this.components = new Array();
    
    function Add(mapid,id,type){
        if( (null != id) && (!self.Contains(id)) ){
            var n = new IMS2_Zoombar(mapid,id,type);
            n.Init();
            self.components[self.components.length] = n;
        }
    }
    this.Add = Add;
    
    function Update(mapctl){
        if(mapctl){
            var mapid = mapctl.mapid;
            if(mapid){
                for(var i = 0; i < self.components.length; i++){
                    var curComp = self.components[i];
                    if(curComp && (curComp.mapid == mapid) && "Slider" != curComp.type){
                        curComp.Update(mapctl);
                    }
                }
                for(var i = 0; i < self.components.length; i++){
                    var curComp = self.components[i];
                    if(curComp && (curComp.mapid == mapid) && "Slider" == curComp.type){
                        curComp.Update(mapctl);
                    }
                }
            }
        }
    }
    this.Update = Update;
    
    function TriggerResize(){
        for(var i = 0; i < self.components.length; i++){
            var curComp = self.components[i];
            if(curComp){
                curComp.TriggerResize();
            }
        }
    }
    this.TriggerResize = TriggerResize;
    
    function Contains(id){
        return(false);
    }
    this.Contains = Contains;
    
    function Get(id){
        var obj = null;
        for(var i = 0; i < self.components.length; i++){
            var cur = self.components[i];
            if((null != cur) && cur.id == id){
                obj = cur;
                break;
            }
        }
        return(obj);
    }
    this.Get = Get;
}

function IMS2_RegisterZoombarControl(mapid,id,type){
    if(IMS2_Zoombars){
        IMS2_Zoombars.Add(mapid,id,type);
    }
}

function IMS2_GetZoombarDiv(id){
    return(document.getElementById("_zoombar_" + id));
}

function IMS2_TriggerZoombarResize(){
    if(IMS2_Zoombars){
        IMS2_Zoombars.TriggerResize();
    }
}

function IMS2_ZoombarRatioSkew(val){
    var n = 1-val;
    var n = n * n;
    return(1-(n*n));
}

function IMS2_ZoombarRatioUnskew(val){
    return(1-(Math.pow((1-val),0.25))); //0.3333333333333333
}

var IMS2_Zoombars = new IMS2_ZoombarManager();