/**
 * @fileOverview A collection of objects for the regional map control.
 * @name RectangularZoom
 */

/** 
 * Regional Map Control object
 * @constructor
 * @property {int} [iZoomDifference] the difference in the zoom level between the parent map and the regional map
 * @property {int} [iHeight] the regional map height 
 * @property {int} [iWidth] the regional map width
 * @property {string} [sMapType] the map type of the regional map, if set to "auto" it will mimic the parent map's type
 */
 function RegionalMapControl(iZoomDifference, iHeight, iWidth, sMapType){
	this.imgBackgroundDirectory = "/includes/images/regional-map/background/";
	this.imgSprite = "/includes/images/regional-map/sprites/overview_map.png";
	this.iShadeOpacity = 60;
	this.visible = true;
	
	//Height
	if(iHeight)
		this.iHeight = iHeight;
	else
		this.iHeight = 100;

	//Width
	if(iWidth)
		this.iWidth = iWidth;
	else
		this.iWidth = 150;
	
	//Zoom Difference
	if(!iZoomDifference && iZoomDifference != 0){
		this.iZoomDifference = 2;
	}
	else {
		if(Math.abs(iZoomDifference) > 16){
			throw "Zoom Level Difference must be -16 to 16!";
		}
		else {
			this.iZoomDifference = iZoomDifference;
		}
	}
	
	//Map Type
	if(sMapType)
		this.sMapType = sMapType;
	else
		this.sMapType = "auto";
			

	this.position = new MQA.MapCornerPlacement(MQA.MapCorner.BOTTOM_RIGHT, new MQA.Size(0, 0));
	this.map = null;
	
	/** 
	 * set the regional maps type
	 * @function
	 * @param {string} mt the map type to set the map to 
	 */
	this.setMapType = function(mt){
		this.mapType = mt;
		if(this.mqMap){
			if(this.mapType != "auto"){
				this.mqMap.setMapType(this.mapType);
			}
			else {
				this.mqMap.setMapType(this.map.getMapType());
			}
		}
	}

	/** 
	 * set the zoom difference between the regional map and the parent map
	 * @function
	 * @param {int} iZoomDifference is the difference in zoom levels.
	 */
	this.setZoomDifference =function(iZoomDifference){
		if(!iZoomDifference && iZoomDifference != 0){
			this.iZoomDifference = 2;
		}
		else {
			if(Math.abs(iZoomDifference) > 16){
				throw "Zoom Level Difference must be -16 to 16!";
			}
			else {
				this.iZoomDifference = iZoomDifference;
			}
		}
		this._mainEvent();
	}
	
	
	/** 
	 * fix IE6 Transparency issue
	 * @function
	 * @param {Image} img the image to fix
	 */
	this._fixIE6PNG = function(obj, h, w){
		if(navigator.appName == "Microsoft Internet Explorer"){
			if(navigator.userAgent.indexOf('MSIE 6')>0){
				if(obj.src){
					var span = document.createElement("span");
					if(obj.id)
						span.id = obj.id;
					if(obj.className)
						span.className = obj.className;
					if(obj.title)
						span.title = obj.title;
					if(obj.style.cssText)
						span.style.cssText = obj.style.cssText;
					span.style.display = "inline-block";
					span.style.width = w;
					span.style.height = h;
					span.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'" + obj.src + "\', sizingMethod='scale')"; 
					return span;
				}
				else {
					var bkgrndImg = obj.style.backgroundImage;
					if(bkgrndImg){
						bkgrndImg = bkgrndImg.substring(4, bkgrndImg.length - 1);
						obj.style.backgroundImage = "";
						obj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'" + bkgrndImg + "\', sizingMethod='scale')"; 
					}
				}
				
			}
		}
		return obj;
	}
	
	/** 
	 * render this as a html element
	 * @function
	 */
	this._render = function(){
		
		this.elem = document.createElement("div"); 
		this.elem.style.position = "absolute"; 
		this.elem.style.height = this.iHeight;
		this.elem.style.width = this.iWidth;
		this.elem.style.backgroundColor = "transparent";
		this.elem.style.overflow = "hidden";
		this.elem.style.cursor = "pointer";
		
		this.mapDiv = document.createElement("div");
		this.mapDiv.style.height = this.iHeight;
		this.mapDiv.style.width = this.iWidth;
		this.elem.appendChild(this.mapDiv);
		
		this.shade = document.createElement("div"); 
		this.shade.style.background = "transparent url(" + this.imgBackgroundDirectory  + "filler_middle.png) repeat 0px 0px";
		this.shade.style.position = "absolute"; 
		this.shade.style.zIndex = 100;
		this.shade.style.border = "1px solid black";
		this.shade.name = "shade";
		this.shade = this._fixIE6PNG(this.shade);
		this.elem.appendChild(this.shade);		
		
		
		this.mqMap = new MQA.TileMap(this.mapDiv);
		this.mqMap.enableDragging(false);
		if(this.sMapType != "auto")
			this.mqMap.setMapType(this.sMapType);
		this.mqMap.setLogoPlacement(MQA.MapLogo.MAPQUEST, new MQA.MapCornerPlacement(MQA.MapCorner.BOTTOM_RIGHT, new MQA.Size(500, 0)));
		this.mqMap.setLogoPlacement(MQA.MapLogo.SCALES, new MQA.MapCornerPlacement(MQA.MapCorner.BOTTOM_RIGHT, new MQA.Size(500, 0)));
		this.mqMap.setLogoPlacement(MQA.MapLogo.NAVTEQ_COPYRIGHT, new MQA.MapCornerPlacement(MQA.MapCorner.BOTTOM_RIGHT, new MQA.Size(500, 0)));
		this.mqMap.setLogoPlacement(MQA.MapLogo.MAPQUEST_COPYRIGHT, new MQA.MapCornerPlacement(MQA.MapCorner.BOTTOM_RIGHT, new MQA.Size(500, 0)));
		this.mqMap.setLogoPlacement(MQA.MapLogo.ICUBED_COPYRIGHT, new MQA.MapCornerPlacement(MQA.MapCorner.BOTTOM_RIGHT, new MQA.Size(500, 0)));
		
		
		this.cover = document.createElement("div");
		this.cover.style.height = this.iHeight;
		this.cover.style.width = this.iWidth;
		this.cover.name = "cover";
		this.cover.style.position = "absolute"; 
		this.cover.style.zIndex = 110;
		this.cover.style.top = 0;
		this.cover.style.left = 0;
		this.cover.style.opacity = 0;
		this.cover.style.filter = 'alpha(opacity=0)';
		this.cover.style.backgroundColor = "#e0e0e0";
		this.cover.style.cursor = "pointer";
		this.elem.appendChild(this.cover);
		
		
		
		var div = document.createElement("div");
		div.style.position = "absolute";
		div.style.zIndex = 105;
		div.style.top = 0;
		div.style.left = 0;
		div.style.width = 10;
		div.style.height = 10;
		div.style.background = "transparent url(" + this.imgBackgroundDirectory  + "upper_left.png) no-repeat 0px 0px";
		div = this._fixIE6PNG(div);
		this.elem.appendChild(div);
		
		var div = document.createElement("div");
		div.style.position = "absolute";
		div.style.zIndex = 105;
		div.style.width = 10;
		div.style.height = 10;
		div.style.top = parseInt(this.elem.style.height) - parseInt(div.style.height);
		div.style.left = 0;
		div.style.background = "transparent url(" + this.imgBackgroundDirectory  + "lower_left.png) no-repeat 0px 0px";
		div = this._fixIE6PNG(div);
		this.elem.appendChild(div);
		
		var div = document.createElement("div");
		div.style.position = "absolute";
		div.style.zIndex = 105;
		div.style.width = 10;
		div.style.height = 10;
		div.style.top = 0;
		div.style.left = parseInt(this.elem.style.width) - parseInt(div.style.width);
		div.style.background = "transparent url(" + this.imgBackgroundDirectory  + "upper_right.png) no-repeat 0px 0px";
		div = this._fixIE6PNG(div);
		this.elem.appendChild(div);
		
		var div = document.createElement("div");
		div.style.position = "absolute";
		div.style.zIndex = 105;
		div.style.width = 10;
		div.style.height = 10;
		div.style.top = parseInt(this.elem.style.height) - parseInt(div.style.height);
		div.style.left = parseInt(this.elem.style.width) - parseInt(div.style.width);
		div.style.background = "transparent url(" + this.imgBackgroundDirectory  + "lower_right.png) no-repeat 0px 0px";
		div = this._fixIE6PNG(div);
		this.elem.appendChild(div);
		
		var div = document.createElement("div");
		div.style.position = "absolute";
		div.style.zIndex = 104;
		div.style.width = parseInt(this.elem.style.width);
		div.style.height = 2;
		div.style.lineHeight = div.style.height;
		div.style.top = 0;
		div.style.left = 0;
		div.style.background = "transparent url(" + this.imgBackgroundDirectory  + "filler.png) repeat-x 0px 0px";
		div.style.overflow = "hidden";
		div = this._fixIE6PNG(div);
		this.elem.appendChild(div);
		
		var div = document.createElement("div");
		div.style.position = "absolute";
		div.style.zIndex = 104;
		div.style.width = parseInt(this.elem.style.width);
		div.style.height = 2;
		div.style.lineHeight = div.style.height;
		div.style.top = parseInt(this.elem.style.height) - 2;
		div.style.left = 0;
		div.style.background = "transparent url(" + this.imgBackgroundDirectory  + "filler.png) repeat-x 0px 0px";
		div.style.overflow = "hidden";
		div = this._fixIE6PNG(div);
		this.elem.appendChild(div);
		
		var div = document.createElement("div");
		div.style.position = "absolute";
		div.style.zIndex = 104;
		div.style.width = 2;
		div.style.height = parseInt(this.elem.style.height);
		div.style.top = 0;
		div.style.left = 0;
		div.style.background = "transparent url(" + this.imgBackgroundDirectory  + "filler.png) repeat-y 0px 0px";
		div = this._fixIE6PNG(div);
		this.elem.appendChild(div);
		
		var div = document.createElement("div");
		div.style.position = "absolute";
		div.style.zIndex = 104;
		div.style.width = 2;
		div.style.height = parseInt(this.elem.style.height);
		div.style.top = 0;
		div.style.left = parseInt(this.elem.style.width) - 2;
		div.style.background = "transparent url(" + this.imgBackgroundDirectory  + "filler.png) repeat-y 0px 0px";
		div = this._fixIE6PNG(div);
		this.elem.appendChild(div);

		/*
		this.shadeTop = document.createElement("div");
		this.shadeTop.style.position = "absolute";
		this.shadeTop.style.top = -1;
		this.shadeTop.style.left = -1;
		this.shadeTop.style.width = 10;
		this.shadeTop.style.height = 10;
		this.shadeTop.style.background = "transparent url(" + this.imgSprite + ") no-repeat -4px -7px";
		this.shadeTop = this._fixIE6PNG(this.shadeTop);
		this.shade.appendChild(this.shadeTop);
		
		this.shadeBottom = document.createElement("div");
		this.shadeBottom.style.position = "absolute";
		this.shadeBottom.style.background = "transparent url(" + this.imgSprite + ") no-repeat -5px -21px";
		this.shadeBottom = this._fixIE6PNG(this.shadeBottom);
		this.shade.appendChild(this.shadeBottom);
		*/
		
		this.zoomDif = document.createElement("div");
		this.zoomDif.style.top = 2;
		this.zoomDif.style.left = 2;
		this.zoomDif.style.position = "absolute";
		this.zoomDif.style.height = 14;
		this.zoomDif.style.width = 14;
		this.zoomDif.style.overflow = "hidden";
		this.zoomDif.style.zIndex = 120;
		
		this.zoomDifImg = document.createElement("img");
		this.zoomDifImg.src = this.imgSprite;
		this.zoomDifImg.style.position = "absolute";
		this.zoomDifImg.style.top = -21;
		this.zoomDifImg.style.left = -22;
		this.zoomDifImg.style.zIndex = 125;
		this.zoomDifImg = this._fixIE6PNG(this.zoomDifImg, 39, 42);
		this.zoomDif.appendChild(this.zoomDifImg);		
		
		this.elem.appendChild(this.zoomDif);
	
	}
	
	/** 
	 * if this element is in displayed mode, then put into hidden mode, else put into displayed mode
	 * @function
	 */
	this._hide = function(){
		
		if(this.visible){
			this.visible = false;
			this.zoomDifImg.style.left = -22; 
			this.zoomDifImg.style.top = -4;		
			this.zoomDif = this._fixIE6PNG(this.zoomDif);
			this.elem.style.height = 14;
			this.elem.style.width = 14;
			this.elem.style.top = parseInt(this.elem.style.top) + (this.iHeight - 14);
			this.elem.style.left = parseInt(this.elem.style.left) + (this.iWidth - 14);
		}
		else {
			this.visible = true;
			this.zoomDifImg.style.left = -22; 
			this.zoomDifImg.style.top = -21;	
			this.zoomDif = this._fixIE6PNG(this.zoomDif);
			this.elem.style.height = this.iHeight;
			this.elem.style.width = this.iWidth;		
			this.elem.style.top = parseInt(this.elem.style.top) - (this.iHeight - 14);
			this.elem.style.left = parseInt(this.elem.style.left) - (this.iWidth - 14);
			this._mainEvent()
		}
	}
	
	this._render();
	
	/** 
	 * get the y coordinate of the event of the element that generated it
	 * @function
	 * @param {Event} e the generated event 
	 */
	this._getTop = function(e) {
	  if (!e.offsetY) return e.layerY;
	  else return e.offsetY;
	}
	
	/** 
	 * get the x coordinate of the event of the element that generated it 
	 * @function
	 * @param {Event} e the generated event
	 */
	this._getLeft = function(e) {
	  if (e.layerX) return e.layerX;
	  else return event.offsetX;
	}
	
	/** 
	 * handle map adjustments for all events 
	 * @function
	 */
	this._mainEvent = function(){
		//Adjust Zoom Level
		if(this.visible){
			if(this.mapType == "auto"){
				if(this.map.getMapType() != this.mqMap.getMapType()){
					this.mqMap.setMapType(this.map.getMapType());
				}
			}
		
			var iZoomLevel = this.map.getZoomLevel() - this.iZoomDifference;
			if(iZoomLevel <=0){
				iZoomLevel = 1;
			}
			if(iZoomLevel > 16){
				iZoomLevel = 16;
			}
			
			if(this.mqMap.getZoomLevel() != iZoomLevel)
				this.mqMap.setZoomLevel(iZoomLevel);
				
			//Adjust center;
			var cLL = this.map.getCenter();
			if(!this.mqMap.getCenter().equals(cLL)){
				this.mqMap.setCenter(new MQLatLng(cLL.getLatitude(), cLL.getLongitude()));
			}
			
			//Set map type 
			if(this.sMapType == "auto" && this.map.getMapType() != this.mqMap.getMapType()){
				this.mqMap.setMapType(this.map.getMapType());
			}
			
			//Set Shade
			var lmSize = this.map.getSize();
			
			var tlPnt = new MQPoint();
			tlPnt.setX(0);
			tlPnt.setY(0);
			
			var brPnt = new MQPoint();
			brPnt.setX(lmSize.getWidth());
			brPnt.setY(lmSize.getHeight());
			
			var tlLL = this.map.pixToLL(tlPnt);
			var brLL = this.map.pixToLL(brPnt);
			
			tlPnt = this.mqMap.llToPix(tlLL);
			brPnt = this.mqMap.llToPix(brLL);
			
			this.shade.style.top = tlPnt.getY();
			this.shade.style.left = tlPnt.getX();
			this.shade.style.height = brPnt.getY() - tlPnt.getY();
			this.shade.style.width = brPnt.getX() - tlPnt.getX();
			
			/*if(parseInt(this.shade.height) > 20 && parseInt(this.shade.width) > 20){
				this.shadeTop.style.display = "";
				this.shadeBottom.style.display = "";
				this.shadeBottom.style.top = 1 + parseInt(this.shade.style.height) - parseInt(this.shadeBottom.style.height);
				this.shadeBottom.style.left =  1 + parseInt(this.shade.style.width) - parseInt(this.shadeBottom.style.width);
			}
			else {
				this.shadeTop.style.display = "none";
				this.shadeBottom.style.display = "none";
			}*/
	
			
			if(parseInt(this.shade.style.top) < 0 || parseInt(this.shade.style.left) < 0){
				this.shade.style.display = "none";
			}
			else {
				this.shade.style.display = "";		
			}
		}
	}
	
	/** 
	 * handle the mouse down event
	 * @function
	 * @param {Event} e the generated event
	 */
	this._mousedown = function(e){
		this.drag = true;
		this.startX = this._getLeft(e);
		this.startY = this._getTop(e);
	}
	
	/** 
	 * handle the mouse move event
	 * @function
	 * @param {Event} e the generated event
	 */
	this._mousemove = function(e){
		if(this.drag){
			var x = this._getLeft(e);
			var y = this._getTop(e);
			
			var dX = this.startX - x;
			var dY = this.startY - y;
			
		
			var size = this.mqMap.getSize();
			
			var pnt = new MQPoint();
			pnt.setX(Math.round(size.getWidth()/2) + dX);
			pnt.setY(Math.round(size.getHeight()/2) + dY);
			
			this.centerLL = this.mqMap.pixToLL(pnt);
			this.mqMap.setCenter(this.centerLL);
			
			this.startX = x;
			this.startY = y;
			
		}
	}
	
	/** 
	 * handle the mouse up event
	 * @function
	 * @param {Event} e the generated event
	 */
	this._mouseup = function(e){
		if(this.drag){
			this._regionalEvent();
		}
		this.drag = false;
		
	}
	
	/** 
	 * handle events generated by the regional map that will effect the parent map
	 * @function
	 */
	this._regionalEvent = function(){
		//Adjust center;
		var cLL = this.mqMap.getCenter();
		if(!this.map.getCenter().equals(cLL)){
			this.map.setCenter(new MQLatLng(cLL.getLatitude(), cLL.getLongitude()));
		}
	}
	
	this.getHeight = function(){ return this.iHeight;};
	this.getWidth = function(){ return this.iWidth;};
	this.getPosition = function(){ return this.position;};
	this.initialize = function(map){
		this.map = map;
		this.draw();
	}
	
	
	this.draw = function(){
		this.elem.style.top = "405px";
		this.elem.style.left = "567px";
		this.map.parent.appendChild(this.elem);
	
		EventManager.addEvent(this.cover, "mousedown", this._mousedown, this);
		EventManager.addEvent(this.cover, "mouseup", this._mouseup, this);
		EventManager.addEvent(this.cover, "mousemove", this._mousemove, this);
		EventManager.addEvent(this.cover, "mouseout", this._mouseup, this);
		EventManager.addEvent(this.zoomDifImg, "click", this._hide, this);
	
		MQA.EventManager.addListener(this.map,"zoomend", this.eventCallback("_mainEvent"));
		MQA.EventManager.addListener(this.map,"move", this.eventCallback("_mainEvent"));
		
		MQA.EventManager.addListener(this.map,"maptypechanged", this.eventCallback("_mainEvent"));
		
		this._mainEvent();
	}
	
	/** 
	 * create MQEventManager callback function
	 * @function
	 * @param {function} f_0 callback function on this 
	 */
	this.eventCallback = function(f_0){
		var c21 = this;
		return function(event){if(!event){event = window.event;}c21[f_0](event);};
	}
}



