/*
 * Summary:
 * With DesignTester you are able to compare the current web page with the original design
 * 
 * Dependencies:
 * - Estate.Core
 * - Estate.Develop.Core
 * - /css/develop.css
 * 
 * Requirements:
 * - The additional CSS styles should be in place in the CSS-file.
 * - For each page there should be a png-file with the same name in the folder
 *   /images/designTester/. So if you have a file called "index.aspx", there should
 *   also be a file called "index.png"
 * 
 * Usage:
	//Set up:
	Estate.Events.AddEvent(
		window, 
		function() {
			Estate.Develop.DesignTester.SetXOffset(0)   // 0 is default
 			Estate.Develop.DesignTester.SetYOffset(10)   // 0 is default
 			Estate.Develop.DesignTester.SetOverlayImageType("png")   // 'png' is default
 			Estate.Develop.DesignTester.SetOverlayImagePath("")   // '/images/DesignTester/' is default
  			Estate.Develop.DesignTester.Init('containerMain')
 		},
		"onload"
	)
	
	//Reset source of image overlay after a page change, eg an AJAX action
	Estate.Develop.DesignTester.SetOverlayImageFileName('index-login');
 */

Estate.Develop.DesignTester = ( function() {
	/* START PRIVATE */
	var OverlayImageId = "DesignTester_Img";
	var OverlayImageType = "png";
	var OverlayImagePath = "/Estate/Images/DesignTester/";
	var OverlayImagePositionSet = false;
	var OverlayImageLinkId = "DesignTester_Link";
	var MeasurementFeedbackBoxId = "DesignTester_Measure"
	var XOffset = -60;
	var YOffset = 0;
	var RequestURL = "";
	


	function ShowOriginalDesign( OverlayImageId, MainContainerWebsiteId ) {
		if (arguments.length == 2 ||
			(arguments.length == 3 && arguments[2] == 92)
			) {
			if (OverlayImagePositionSet == false) {
				PlaceOverlay( OverlayImageId, MainContainerWebsiteId )
			}
			ToggleVisibility( OverlayImageId )
		}
	}
	
	function PlaceOverlay( OverlayImageId, MainContainerWebsiteId ) {
		var OverlayImageX = Estate.Layers.GetPositionX( document.getElementById( MainContainerWebsiteId ) ) + XOffset
		var OverlayImageY = Estate.Layers.GetPositionY( document.getElementById( MainContainerWebsiteId ) ) + YOffset
		document.getElementById(OverlayImageId).style.left = OverlayImageX + 'px'
		document.getElementById(OverlayImageId).style.top = OverlayImageY + 'px'
		OverlayImagePositionSet = true
	}
	
	function MoveOverlay( OverlayImageId, MainContainerWebsiteId, KeyID ) {
		if (document.getElementById(OverlayImageId).style.display == "block") {
			var MoveInteger
			var MoveInterval = 10
			var OverlayImagePositionX
			var OverlayImagePositionY
			
			// Move overlay image up or right
			if ( KeyID == 46 || KeyID == 93 || KeyID == 62 || KeyID == 125 ) {
				MoveInteger = 1
			}
			// Move overlay image down or left
			if ( KeyID == 44 || KeyID == 91 || KeyID == 60 || KeyID == 123 ) {
				MoveInteger = -1
			}
	
			// Move in larger steps by holding "Shift"-key
			if ( KeyID == 60 || KeyID == 62 || KeyID == 123 || KeyID == 125 ) {
				MoveInteger = MoveInteger * MoveInterval
			}
			
			// Apply movement on the Y-axis
			if ( KeyID == 44 || KeyID == 46 || KeyID == 60 || KeyID == 62 ) {
				OverlayImagePositionY = Estate.Layers.GetPositionY( document.getElementById( OverlayImageId ) )
				document.getElementById(OverlayImageId).style.top = ( OverlayImagePositionY + MoveInteger) + "px"
			}
			// Apply movement on the X-axis
			if ( KeyID == 91 || KeyID == 93 || KeyID == 123 || KeyID == 125 ) {
				OverlayImagePositionX = Estate.Layers.GetPositionX( document.getElementById( OverlayImageId ) )
				document.getElementById(OverlayImageId).style.left = ( OverlayImagePositionX + MoveInteger) + "px"
			}
	
			// Show movement of overlay from previouse position in pixels (Y-axis)
			if ( KeyID == 44 || KeyID == 46 || KeyID == 60 || KeyID == 62 ) {
				var MeasurementFeedbackBox_Y = document.getElementById(MeasurementFeedbackBoxId +'_Y')
				MeasurementFeedbackBox_Y.innerHTML = (MoveInteger + parseInt(MeasurementFeedbackBox_Y.innerHTML))
				document.getElementById(MeasurementFeedbackBoxId).style.display = 'block'
			}
			// Show movement of overlay from previouse position in pixels (X-axis)
			if ( KeyID == 91 || KeyID == 93 || KeyID == 123 || KeyID == 125 ) {
				var MeasurementFeedbackBox_X = document.getElementById(MeasurementFeedbackBoxId +'_X')
				MeasurementFeedbackBox_X.innerHTML = (MoveInteger + parseInt(MeasurementFeedbackBox_X.innerHTML))
				document.getElementById(MeasurementFeedbackBoxId).style.display = 'block'
			}
		}
	}

	function ToggleVisibility( OverlayImageId ) {
		var el = document.getElementById(OverlayImageId);
	
		if (el.style.display == '') {
			el.style.display = 'block';
			Estate.Develop.CheckImage.Run( RequestURL )
		}
		else {
			el.style.display = '';
		}
	}
	
	function PlaceDesignTesterHTML() {
		Estate.Develop.TesterButtonHolder.Add()
		var TesterButtonHolderElement = Estate.Develop.TesterButtonHolder.GetTesterButtonHolderElement()

		var OverlayImageLink = document.createElement("div")
		OverlayImageLink.id = OverlayImageLinkId
		OverlayImageLink.title = "Click here or Press '\\' to check this page with the original design."
		OverlayImageLink.innerHTML = "TEST<br />DESIGN"
		TesterButtonHolderElement.appendChild(OverlayImageLink)
		
		var OverlayImage = document.createElement("img")
		OverlayImage.id = OverlayImageId
		OverlayImage.src = "overlay.png"
		OverlayImage.title = "Press one of the following keys to move the overlay image: ,.[]. Press Shift to move faster."
		OverlayImage.alt = "Original design"
		document.body.appendChild(OverlayImage)
		
		Estate.Develop._DragDrop.Init( OverlayImage );
		Estate.Develop._DragDrop.InitDesignTesterFeedback();

		var MeasurementFeedbackBox = document.createElement("div")
		MeasurementFeedbackBox.id = MeasurementFeedbackBoxId
		MeasurementFeedbackBox.innerHTML  = '	X: <span id="DesignTester_Measure_X">0</span><br />'
		MeasurementFeedbackBox.innerHTML += '	Y: <span id="DesignTester_Measure_Y">0</span>'
		MeasurementFeedbackBox.innerHTML += '	<div id="DesignTester_Measure_Reset" title="Reset counter">Reset</div>'
		document.body.appendChild(MeasurementFeedbackBox)
	}
	
	function SetOverlayImageSource() {
		var OverlayImage = document.getElementById(OverlayImageId)
		var PageFileName = Estate.StringTools.GetFilenameFromUrl()
		var ImageFileName = PageFileName.substring(0, PageFileName.lastIndexOf("."));
		
		if (ImageFileName == "")  {
			ImageFileName = "index"
		}
		
		RequestURL = OverlayImagePath + ImageFileName + "."+ OverlayImageType
		
		OverlayImage.src = RequestURL
	}
	/* END PRIVATE */
	
	
	
	/* START PUBLIC */
	return {
		// Adds HTML and events to HTML document
		Init: function( MainContainerWebsiteId ) {
			var error 
			error = Estate.Check.ArgumentsCount( arguments.length, 1 );
			if ( error != "" ) throw new Error( error );
			error = Estate.Check.ElementById( MainContainerWebsiteId );
			if ( error != "" ) throw new Error( error );
			

			PlaceDesignTesterHTML()
			SetOverlayImageSource()
			
			document.getElementById( OverlayImageLinkId ).onclick = function() { ShowOriginalDesign( OverlayImageId, MainContainerWebsiteId ) }
			document.getElementById( 'DesignTester_Measure_Reset' ).onclick = function() { document.getElementById(MeasurementFeedbackBoxId+"_X").innerHTML = 0
																							 document.getElementById(MeasurementFeedbackBoxId+"_Y").innerHTML = 0
																						   }
			Estate.Events.AddEvent ( document,
									function(e) { var KeyID = (window.event) ? event.keyCode : e.which;
														MoveOverlay(OverlayImageId, MainContainerWebsiteId, KeyID)
														ShowOriginalDesign(OverlayImageId, MainContainerWebsiteId, KeyID)
														},
									"onkeypress"
									)
			Estate.Events.AddEvent ( window,
									 function() { OverlayImagePositionSet = false; PlaceOverlay( OverlayImageId, MainContainerWebsiteId ) },
									 "onresize"
									)
		},
		
		/*
		 * Summary:
		 * Reset image overlay source after a page change, eg an AJAX-action
		 * 
		 * Usage:
			Estate.Develop.DesignTester.SetOverlayImageFileName('index-login');
		 */
		SetOverlayImageFileName: function( FileName ) {
			var error
			error = Estate.Check.ArgumentsCount( arguments.length, 1 );
			if ( error != "" ) throw new Error( error );
			error = Estate.Check.VariableType( FileName, "string" );
			if ( error != "" ) throw new Error( error );
			
			var FileNameWithoutExtension = Estate.StringTools.GetFilenameWithoutExtension( FileName )
			
			var OverlayImage = document.getElementById(OverlayImageId)
			OverlayImage.src = OverlayImagePath + FileNameWithoutExtension + "."+ OverlayImageType
		},
		
		// Sets which image extension the design tester should use for the image overlay
		SetOverlayImageType: function( ImageType ) {
			var error
			error = Estate.Check.ArgumentsCount( arguments.length, 1 );
			if ( error != "" ) throw new Error( error );
			error = Estate.Check.VariableType( ImageType, "string" );
			if ( error != "" ) throw new Error( error );
			if (ImageType != "png" && ImageType != "jpg") throw new Error ( "Error: the design tester only accepts png and jpg image formats" )
			
			
			OverlayImageType = ImageType;
		},
		
		// Sets the path where the overlay images are
		SetOverlayImagePath: function( ImagePath ) {
			var error
			error = Estate.Check.ArgumentsCount( arguments.length, 1 );
			if ( error != "" ) throw new Error( error );
			error = Estate.Check.VariableType( ImagePath, "string" );
			if ( error != "" ) throw new Error( error );


			OverlayImagePath = ImagePath;
		},
		
		// Sets the X offset of the overlay images
		SetXOffset: function( NewXOffset ) {
			var error
			error = Estate.Check.ArgumentsCount( arguments.length, 1 );
			if ( error != "" ) throw new Error( error );
			error = Estate.Check.VariableType( NewXOffset, "number" );
			if ( error != "" ) throw new Error( error );


			XOffset += NewXOffset;
		},
		
		// Sets the Y offset of the overlay images
		SetYOffset: function( NewYOffset ) {
			var error
			error = Estate.Check.ArgumentsCount( arguments.length, 1 );
			if ( error != "" ) throw new Error( error );
			error = Estate.Check.VariableType( NewYOffset, "number" );
			if ( error != "" ) throw new Error( error );


			YOffset += NewYOffset;
		}
	};
	/* END PUBLIC */
})();





/* Makes an HTML element draggable */
Estate.Develop._DragDrop = ( function() {
	/* START PRIVATE */
	var startX = 0;
	var startY = 0;
	var offsetX = 0;
	var offsetY = 0;
	var previousX = 0;
	var previousY = 0;
	var dragElement;
	var DesignTesterFeedback = false;

	function OnMouseDown(e) {
		if (e == null) { e = window.event; }
		var target = e.target != null ? e.target : e.srcElement;
		
		if ((e.button == 1 && window.event != null || 
			 e.button == 0)) {
			 
			startX = e.clientX;
			startY = e.clientY;
			previousX = startX;
			previousY = startY;
			offsetX = ExtractNumber(target.style.left);
			offsetY = ExtractNumber(target.style.top);
			dragElement = target;
			dragElement.style.cursor = "move";
			
			Estate.Events.AddEvent( document, OnMouseMove, "onmousemove" )
			
			// prevent text selection or image drag
			document.onselectstart = function () { return false; };
			target.ondragstart = function() { return false; };			
			document.body.focus();
			return false;
		}
	}

	function OnMouseMove(e) {
		if (e == null) { e = window.event; }

		dragElement.style.left = (offsetX + e.clientX - startX) + 'px';
		dragElement.style.top = (offsetY + e.clientY - startY) + 'px';

		if (DesignTesterFeedback == true) {
			var DesignTester_Measure_X = document.getElementById('DesignTester_Measure_X')
			var DesignTester_Measure_Y = document.getElementById('DesignTester_Measure_Y')
			DesignTester_Measure_X.innerHTML = (e.clientX - previousX) + parseInt(DesignTester_Measure_X.innerHTML)
			DesignTester_Measure_Y.innerHTML = (e.clientY - previousY) + parseInt(DesignTester_Measure_Y.innerHTML)
			document.getElementById('DesignTester_Measure').style.display = "block"

			previousX = e.clientX;
			previousY = e.clientY;
		}
	}

	function OnMouseUp(e) {
		if (dragElement != null) {
			document.onmousemove = null;
			document.onselectstart = null;
			dragElement.ondragstart = null;
			dragElement.style.cursor = "";
			dragElement = null;
		}
	}

	function ExtractNumber(value) {
		var n = parseInt(value);		
		return n == null || isNaN(n) ? 0 : n;
	}
	/* END PRIVATE */

	
	
	/* START PUBLIC */
	return {
		Init: function( element ) {
			Estate.Events.AddEvent( element, OnMouseDown, "onmousedown" )
			Estate.Events.AddEvent( element, OnMouseUp, "onmouseup" )
		},
		
		InitDesignTesterFeedback: function( OverlayStartX, OverlayStartY ) {
			DesignTesterFeedback = true;
			var startX = OverlayStartX;
			var startY = OverlayStartY;
		}
	}
})();






/* Makes an HTML element draggable */
Estate.Develop.CheckImage = ( function() {
	/* START PRIVATE */
	var oRequest;
	if (window.XMLHttpRequest) {
		oRequest = new XMLHttpRequest();
	} else if (window.ActiveXObject) {
		oRequest = new ActiveXObject("Microsoft.XMLHTTP");
	}
	/* END PRIVATE */

	
	
	/* START PUBLIC */
	return {
		Run: function( url ) {
			if (oRequest != undefined) {
				oRequest.onreadystatechange = function() {Estate.Develop.CheckImage.Feedback( url );};
				oRequest.open("GET", url, true);
				oRequest.send("");
			}
		},
		
		Feedback: function( url ) {
			if (oRequest.readyState == 4) { // only if req is "loaded"
				if (oRequest.status != 200 && oRequest.status != 304) {
					Estate.Trace(
						"Design tester image could not be loaded.<br />"+
						"&ensp; Expected image URL: "+ url +"<br />"+
						"&ensp; Error code: "+ oRequest.status +" "+ oRequest.statusText
					)
				}
			}
		}
	}
})();

