/* ***********************************************************
Copyright 2006 SolidWorks Corp.  
All Rights Reserved.
************************************************************ */



// global variables.

var wnWidth = 0;
var wnHeight = 0;
var numVisDivs = 3;
var imgSize = 350;
var fileName = "";
var isBlankDir = false;
var prevClientX = 0;
var prevClientY = 0;
var isPopupVisible = false;

var numOfLayers = 3;
var layers = [];
var activeLayer = 0;

var request = null;

var fileBrowser = null;

var zoomInOutMode = false;
var zoomingIn	= true;
var zoominInArea = false;

var activePanImg = null;
var panXDir = 0;
var panYDir = 0;

var isAuthorizedUser = false;
var newLayerTimeStamp = 0;

// after zoom and before recapture, pan is a problem. 
// don't allow panning in that interval.
var suspendPan = false;

var selectedSheetIndex = 0;
var oldSheetNames = [];
var oldFileName = fileName;


//========================================================
//========== Initializing things =========================
//========================================================
// Assign event handlers used by both Navigator and IE
function initViewer() 
{
//	debugger
	wnWidth = 0;
	wnHeight = 0;
	numVisDivs = 3;
	imgSize = 350;
	prevClientX = 0;
	prevClientY = 0;
	
	numOfLayers = 3;
	clearAllLayers();
	layers = [];
	activeLayer = 0;
	
    if (document.layers) 
    {
        // turn on event capture for these events in NN4 event model
        document.captureEvents(Event.MOUSEDOWN | Event.MOUSEMOVE | Event.MOUSEUP);
        return;
    }
    
  	document.onmousedown = startDrag;
   	document.onmousemove = doDrag;
   	document.onmouseup = endDrag;
   	document.onkeyup = handleKeyEvent;
   	window.onresize = recenterDivs;
   	//window.onscroll = recenterDivs;

	if (window.addEventListener)
        window.addEventListener('DOMMouseScroll', zoomIt, false);
	window.onmousewheel = document.onmousewheel = zoomIt;

    wnWidth = getViewportWidth();
    wnHeight = getViewportHeight();
    var smaller = (wnWidth < wnHeight) ? wnWidth : wnHeight;
    numVisDivs = Math.floor(smaller/imgSize);
    if (numVisDivs < 1)
		numVisDivs = 1;
    
    //numVisDivs = 1;
    
    prevClientX = Math.round(wnWidth/2);
    prevClientY = Math.round(wnHeight/2);
    
    getRequest();
    
    var tempFileName = getURLParamValue("file");
    if (tempFileName)
        fileName = tempFileName;
        
    if (isVisible("BlankDirImg") == true)
    {
		isBlankDir = true;
		moveElementToCenter(100, "BlankDirImg");
	}
		
    
	activeLayer = 0;
	newLayerTimeStamp = new Date().getTime();

	layers[0] = new CLayer(0, true);
	layers[1] = new CLayer(1, false);
	layers[2] = new CLayer(2, false);
	
	var fader = getElement("fader");
	fader.style.width = "" + 2000 + "px"
	fader.style.height = "" + 2000 + "px"
	fader.onmousedown = clearSelectedFile;
	
	initFileBrowser();
	fileBrowser = getFileBrowser();
    fileBrowser.mainDiv.ondblclick  = onBrowseToFile;

	initToolBar();
	initMailPopup();
	initLoginPopup();
	initSheets();
	document.body.style.cursor='move';
    return;
}

function recenterDivs()
{
	
	moveElementToCenter(10, "navToolbar");
	moveElementToCenter(100, "mailPopup");
	moveElementToCenter(100,"browsePopup");
}

function initSheets()
{
	getSheetNames();
	var elem = getElement("sheetListBox");
	elem.onmousedown = preSheetChange;
	elem.onchange = onSheetChange;
}

function preSheetChange(evt)
{
	cancelZoomToWindow();
}

function onSheetChange(evt)
{
	cancelZoomToWindow();
	evt = evt ? evt : event;
	if (!evt)
		return;
	
	var sheetChanged = false;
	var elem = getElement("sheetListBox");
	for (var i = 0; i < elem.options.length; i++)
	{
		if (elem.options[i].selected)
		{
			if (i != selectedSheetIndex)
			{
				selectedSheetIndex = i;
				sheetChanged = true;
				oldFileName = fileName;
			}
			break;
		}
	}
	
	if (sheetChanged)
	{
		elem.blur() ;
		initViewer();
	}
	
}

function getSheetNames()
{
	// if we changed the file
	if (oldSheetNames.length > 0 && oldFileName == fileName)
	{
		var elem = getElement("sheetListBox");
		elem.options.length = 0;
		for (var i = 0; i < oldSheetNames.length; i++)
		{
			var name = oldSheetNames[i];
			if (i == selectedSheetIndex)
				elem.options[i] = new Option(name,i,false,true);
			else
				elem.options[i] = new Option(name,i,false,false);
		}
	}
	else
	{
		var request = getRequest();
		var url = "asyncH.aspx?get_sheets=1&dummy=" + new Date().getTime();;
		request.open("GET",url,true);
		request.onreadystatechange = afterGettingSheetNames;
		request.send(null);
	}
}

function afterGettingSheetNames()
{
	if (request.readyState == 4)
	{
		//var retVal = request.responseText;
		//alert(retVal);
		
		var xmlDoc = request.responseXML;
		var count = xmlDoc.getElementsByTagName("count")[0].firstChild.nodeValue;
		//alert(count);
		oldSheetNames = new Array();
		oldFileName = fileName;
		
		// we are loading sheet names for new drawings only. 
		// always load first sheet by default.
		selectedSheetIndex = 0;

			
		var elem = getElement("sheetListBox");
		elem.options.length = 0;
		for (var i = 0; i < count; i++)
		{
			var name = xmlDoc.getElementsByTagName("name")[i].firstChild.nodeValue;
			if (i == selectedSheetIndex)
				elem.options[i] = new Option(name,i,false,true);
			else 
				elem.options[i] = new Option(name,i,false,false);
				
			oldSheetNames[i] = name;
		}
		
//		elem.options[1] = new Option("sheet2",1,false,false);
//		oldSheetNames[1] = "sheet2";
//		elem.options[2] = new Option("sheet3",2,false,false);
//		oldSheetNames[2] = "sheet3";
	}
}

function onBrowseToFile(evt)
{
	var tempFileName = fileBrowser.onBrowseToFile(evt);
	if (!tempFileName)
		return;
		
	    
	hideAllPopups();
    window.location = "main.aspx?file=" + tempFileName;
//    fileName = tempFileName;
//    initViewer();
}


function getRequest()
{
	request = getRequestObject();
	return request;
}

function clearAllLayers()
{
	for (var i = 0; i < 3; i++)
	{
		if (layers[i])
			layers[i].removeAllDivs();
	}

}

function initToolBar()
{
	moveElementToCenter(10, "navToolbar");
	setVisiblity("navToolbar",true);

	// zoom-in control    
	var zoomInImg = getElement("tZoomin");
	zoomInImg.onmousedown = onToolbarZoominSt;
	zoomInImg.onmouseup = onToolbarZoominEnd;

	var zoomInOverImg = getElement("tZoomin_over");
	zoomInOverImg.onmousedown = onToolbarZoominSt;
	zoomInOverImg.onmouseup = onToolbarZoominEnd;
	zoomInOverImg.onblur = onToolbarZoominEnd;

	// zoom-out control
	var zoomOutImg = getElement("tZoomout");
	zoomOutImg.onmousedown = onToolbarZoomOutSt;
	zoomOutImg.onmouseup = onToolbarZoomOutEnd;

	var zoomOutOverImg = getElement("tZoomout_over");
	zoomOutOverImg.onmousedown = onToolbarZoomOutSt;
	zoomOutOverImg.onmouseup = onToolbarZoomOutEnd;

	//zoom to region.
	var zoomRgnImg = getElement("tZoomToRegion");
	//zoomRgnImg.onmousedown = onToolbarZoomToAreaSt;
	//zoomRgnImg.onmouseup = onToolbarZoomToAreaEnd;
	zoomRgnImg.onmouseup = onToolbarZoomToAreaSt;

	var zoomRgnOverImg = getElement("tZoomToRegion_over");
	zoomRgnOverImg.onmousedown = onToolbarZoomToAreaCancel;//onToolbarZoomToAreaSt;
	zoomRgnOverImg.onmouseup = onToolbarZoomToAreaCancel;//onToolbarZoomToAreaEnd;

	// zoom to fit
	var zoomToFitImg = getElement("tZoomToFit");
	zoomToFitImg.onmousedown = onToolbarZoomToFitSt;
	zoomToFitImg.onmouseup = onToolbarZoomToFitEnd;
	
	var zoomToFitOverImg = getElement("tZoomToFit_over");
	zoomToFitOverImg.onmousedown = onToolbarZoomToFitSt;
	zoomToFitOverImg.onmouseup = onToolbarZoomToFitEnd;

//	// pan
//	var panImg = getElement("tPan");
//	panImg.onmousedown = panByDeltaSt;
//	panImg.onmouseup = panByDeltaEnd;
//	
//	var panUpImg = getElement("tPan_up");
//	panUpImg.onmousedown = panByDeltaSt;
//	panUpImg.onmouseup = panByDeltaEnd;

//	var panDowmImg = getElement("tPan_down");
//	panDowmImg.onmousedown = panByDeltaSt;
//	panDowmImg.onmouseup = panByDeltaEnd;

//	var panLeftImg = getElement("tPan_left");
//	panLeftImg.onmousedown = panByDeltaSt;
//	panLeftImg.onmouseup = panByDeltaEnd;

//	var panRightImg = getElement("tPan_right");
//	panRightImg.onmousedown = panByDeltaSt;
//	panRightImg.onmouseup = panByDeltaEnd;

	// browse
	var browseImg = getElement("tBrowse");
    browseImg.onmousedown = onBrowseToolbarSt;
    browseImg.onmouseup = onBrowseToolbarEnd;
	
	var browseOverImg = getElement("tBrowse_over");
    browseOverImg.onmousedown = onBrowseToolbarSt;
    browseOverImg.onmouseup = onBrowseToolbarEnd;

	var printImg = getElement("tPrint");
    printImg.onmousedown = onPrintToolbarSt;
    printImg.onmouseup = onPrintToolbarEnd;
	
	var printOverImg = getElement("tPrint_over");
    printOverImg.onmousedown = onPrintToolbarSt;
    printOverImg.onmouseup = onPrintToolbarEnd;
    
	var quitButton1 = getElement("quitButton1");
	quitButton1.onmousedown = onQuit;
	var quitButton2 = getElement("quitButton2");
	quitButton2.onmousedown = onQuit;
	
    
}

function panByDeltaEnd(evt)
{
//	swapVisibility(activePanImg,"tPan");
//	activePanImg = null;
//    for (var i = 0; i < numOfLayers; i++)
//	{
//		if (layers[i])
//			layers[i].panByDelta(evt, panXDir, panYDir);
//	}
//	
//	panXDir = 0;
//	panYDir = 0;
	
}

function panByDeltaSt(evt)
{
//    evt = (evt) ? evt : event;

//	var panImg = getElement("tPan");
//	
//	var imgWidth = getElementWidth(panImg);
//	var imgHeight = getElementHeight(panImg);

//    var offX = (panImg.offsetLeft || panImg.offsetTop) ? panImg.offsetLeft : panImg.left;
//    var offY = (panImg.offsetLeft || panImg.offsetTop) ? panImg.offsetTop : panImg.top;
//	
//	var toolbarImg = getElement("navToolbar");
//    var navX = (toolbarImg.offsetLeft || toolbarImg.offsetTop) ? toolbarImg.offsetLeft : toolbarImg.left;
//    var navY = (toolbarImg.offsetLeft || toolbarImg.offsetTop) ? toolbarImg.offsetTop : toolbarImg.top;
//	
//	offX += navX;
//	offY += navY;
//	
//	
//    var mouseX = evt.pageX ? evt.pageX : evt.clientX;
//    var mouseY = evt.pageY ? evt.pageY : evt.clientY;
//	
//	var deltaX = (mouseX - offX) - Math.round(imgWidth/2);
//	var deltaY = (mouseY - offY) - Math.round(imgHeight/2);
//	
//	var xdir = (Math.abs(deltaX) > Math.abs(deltaY)) ? 1 : 0;
//	var ydir = xdir == 1 ? 0 : -1;
//	if (deltaX < 0)
//		xdir *= -1; 
//	if (deltaY > 0)
//		ydir *= -1; 
//	
//	if (xdir == 1)
//		activePanImg = "tPan_right";
//	else if (xdir == -1)
//		activePanImg = "tPan_left";
//	else if (ydir == 1)
//		activePanImg = "tPan_down";
//	else if (ydir == -1)
//		activePanImg = "tPan_up";
//		
//    swapVisibility("tPan",activePanImg);
//    
//	panXDir = xdir;
//	panYDir = ydir;
//    
////    for (var i = 0; i < numOfLayers; i++)
////	{
////		if (layers[i])
////			layers[i].panByDelta(evt, xdir, ydir);
////	}
//	
	return false;
	
}

function zoomToFitServerStatus()
{
	if (request.readyState == 4)
	{
		var retVal = request.responseText;
		//alert(retVal);
	}
}

function onToolbarZoomToFitSt(evt)
{
	cancelZoomToWindow();
	swapVisibility("tZoomToFit","tZoomToFit_over");
}

function onToolbarZoomToFitEnd(evt)
{
//	var request = getRequest();
//	var url = "asyncH.aspx?recache=" + fileName + "&dummy=" + new Date().getTime();
//	request.open("GET",url,true);
//	request.onreadystatechange = zoomToFitServerStatus;
//	request.send(null);
	
	initViewer();
	
	swapVisibility("tZoomToFit_over","tZoomToFit");
}

function onToolbarZoomToAreaSt(evt)
{
	swapVisibility("tZoomToRegion","tZoomToRegion_over");
//	if (document.all)
//		document.body.style.cursor="url('Appimage/zoom_region.cur')";
//	else
		document.body.style.cursor="crosshair";
		zoominInArea = true;
	
}

function onToolbarZoomToAreaEnd(evt)
{
	zoominInArea = true;
}


function onToolbarZoomToAreaCancel(evt)
{
	if (zoominInArea)
	{
		zoominInArea = false;
		swapVisibility("tZoomToRegion_over","tZoomToRegion");
		document.body.style.cursor='move';
	}
}

function cancelZoomToWindow()
{
	if (zoominInArea)
	{
		zoominInArea = false;
		swapVisibility("tZoomToRegion_over","tZoomToRegion");
		document.body.style.cursor='move';
		
		for (var i = 0; i < 3; i++)
		{
			if (layers[i])
				layers[i].cancelZoomToWindow();
		}
		
	}
}

function onToolbarZoominSt(evt)
{
	cancelZoomToWindow();
	swapVisibility("tZoomin","tZoomin_over");
}

function onToolbarZoominEnd(evt)
{
	evt = evt ? evt : event;
	
	swapVisibility("tZoomin_over","tZoomin");
	
	zoomInOutMode = true;
	zoomingIn = true;
	zoomIt(evt);
}

function onToolbarZoomOutSt(evt)
{
	cancelZoomToWindow();
	swapVisibility("tZoomout","tZoomout_over");
}

function onToolbarZoomOutEnd(evt)
{
	evt = evt ? evt : event;
	swapVisibility("tZoomout_over","tZoomout");
	
	zoomInOutMode = true;
	zoomingIn = false;
	zoomIt(evt);
}

function onQuit(evt)
{
	hideAllPopups();
}

function hideAllPopups()
{
	isPopupVisible = false;
	setVisiblity("fader",false);
	fileBrowser.hide();
	//setVisiblity("browsePopup",false);
	setVisiblity("mailPopup",false);
	setVisiblity("loginPopup",false);
	
	//document.body.style.cursor='move';
}

function onPrintToolbarSt(evt)
{
	cancelZoomToWindow();
	swapVisibility("tPrint","tPrint_over");
}

function onPrintToolbarEnd(evt)
{
	swapVisibility("tPrint_over","tPrint");
	window.location = "printpage.aspx?file=" + fileName;
	return false;
}

function onBrowseToolbarSt(evt)
{
	cancelZoomToWindow();
	swapVisibility("tBrowse","tBrowse_over");
}

function onBrowseToolbarEnd(evt)
{
	swapVisibility("tBrowse_over","tBrowse");
	setVisiblity("fader",true);
	fileBrowser.show(true);
	//document.body.style.cursor='normal';
	return false;
}

function initMailPopup()
{
	moveElementToCenter(100, "mailPopup");
	setVisiblity("mailPopup",false);
	
	
    var emailImg = getElement("tEmail");
    emailImg.onmousedown = onEmailToolbarSt;
    emailImg.onmouseup = onEmailToolbarEnd;
    
    var emailOverImg = getElement("tEmail_over");
    emailOverImg.onmousedown = onEmailToolbarSt;
    emailOverImg.onmouseup = onEmailToolbarEnd;
}

function onEmailToolbarSt(evt)
{
	cancelZoomToWindow();
	swapVisibility("tEmail","tEmail_over");
}

function onEmailToolbarEnd(evt)
{
	swapVisibility("tEmail_over","tEmail");

	setVisiblity("fader",true);
	setVisiblity("mailPopup",true);
	
    var sendButton = getElement("MailSend");
    sendButton.onmousedown = sendMail;
    //document.body.style.cursor='normal';
	
	return false;
}

function mailStatus()
{
	if (request.readyState == 4)
	{
		var retVal = request.responseText;
		//alert(retVal);
	}
}

function checkEmailAddress(addr) 
{
	if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(addr))
	{
		return true;
	}
	alert("Invalid E-mail Address! Please re-enter.")
	return false;
}

function stripWhiteSpace(s)
{
	if( (s==null) || (typeof(s)!='string') || !s.length)
		return'';
	return s.replace(/\s+/g,'');
}
	
 

function sendMail(evt)
{
    var sendButton = getElement("MailSend");
    var elemTo = getElement("MailTo");

    var elemSubj = getElement("MailSubject");
    
    var subj = escape(elemSubj.value);
    var to = elemTo.value;
    if (!to || !subj)
    {
		alert("Please specify what to send and to whome");
		return;
    }
    
    var to = elemTo.value;
    to = stripWhiteSpace(to);
    var toArr = to.split(";");
	for (var i = 0; i < toArr.length; i++)
	{
		if (checkEmailAddress(toArr[i]) == false)
			return;

		var request = getRequest();
		var url = "asyncH.aspx?To=" + toArr[i] + "&Subject=" + subj + "&ts=" + new Date().getTime();
		request.open("GET",url,true);
		request.onreadystatechange = mailStatus;
		request.send(null);
	
	}	

	hideAllPopups();
	
}

function initLoginPopup()
{
	moveElementToCenter(100, "loginPopup");
	setVisiblity("loginPopup",false);
    var loginImg = getElement("tLogin");
    if (!loginImg)
    {
		isAuthorizedUser = true;
		return;
	}
	isAuthorizedUser = false;
		
    loginImg.onmousedown = onLoginToolbarSt;
    loginImg.onmouseup = onLoginToolbarEnd;
    
    var loginOverImg = getElement("tLogin_over");
    loginOverImg.onmousedown = onLoginToolbarSt;
    loginOverImg.onmouseup = onLoginToolbarEnd;
}

function onLoginToolbarSt(evt)
{
    swapVisibility("tLogin","tLogin_over");
}

function onLoginToolbarEnd(evt)
{
    swapVisibility("tLogin_over","tLogin");
	isPopupVisible = true;
	setVisiblity("fader",true);
	setVisiblity("loginPopup",true);
	//document.body.style.cursor='normal';
	return false;
}

function calcToolXPos(offset)
{
	// assumption is that all the pngs are of size 38
	var centerXPos = Math.round(wnWidth/2) - 32;
	
	return (centerXPos + offset*64);
}

function getNextActiveLayer()
{
	// we will cycle between layers 1 and 2. 
	if (activeLayer == 0)
		return 1;
	
	//layers[0].removeAllDivs();	
	var retVal = (activeLayer == 1) ? 2 : 1;
	
	return retVal;
}

function switchLayer()
{
	var prevLayerIndex = activeLayer;
	var nextLayerIndex = getNextActiveLayer();
	
	var prevLayer = layers[prevLayerIndex];
	var nextLayer = layers[nextLayerIndex];
	
	// copy data needed to recalculate the divs in new layer.
	nextLayer.isActiveLayer = true;
	nextLayer.center["x"] = prevLayer.center["x"];
	nextLayer.center["y"] = prevLayer.center["y"];
	nextLayer.absOrigin["x"] = prevLayer.absOrigin["x"];
	nextLayer.absOrigin["y"] = prevLayer.absOrigin["y"];
	nextLayer.zoom = prevLayer.zoom;
	
	// make the previous layer inactive (no need to create new divs there).
	prevLayer.isActiveLayer = false;
	
	activeLayer = nextLayerIndex;
}

function suspendLayer(lid)
{
	if (!layers[lid]  || !(layers[lid].createdDivs))
		return;
		
    for (var obj in layers[lid].createdDivs)
    {
        var elemObj = layers[lid].createdDivs[obj];
        var currElem = elemObj.element;
	    var stl = getStyle(currElem);
	    stl.visibility = "hidden";
		
		var imgObj = layers[lid].createdImgs[obj];
		var stl2 = getStyle(imgObj);
		stl2.visibility = "hidden";
    }
}

function bringToLifeLayer(lid)
{
	if (!layers[lid]  || !(layers[lid].createdDivs))
		return;
		
    for (var obj in layers[lid].createdDivs)
    {
        var elemObj = layers[lid].createdDivs[obj];
        var currElem = elemObj.element;
	    var stl = getStyle(currElem);
	    stl.visibility = "visible";
		
		var imgObj = layers[lid].createdImgs[obj];
		var stl2 = getStyle(imgObj);
		stl2.visibility = "visible";
    }
}

var layerNotSuspended = 0;
// Turn selected element on
function startDrag(evt) 
{
	if (isVisible("fader") == true)
		return true;
		
	if (suspendPan)
		return;
		
    evt = (evt) ? evt : event;
	
    var shiftPressed = evt.shiftKey ? true : false;
    if (shiftPressed)
    {
		for (var i = 0; i < numOfLayers; i++)
		{
			if (i != layerNotSuspended)
				suspendLayer(i);
			else
				bringToLifeLayer(i);
		}
		
		if (layerNotSuspended == 2)
			layerNotSuspended = 0;
		else
			layerNotSuspended++;
        return false;
    }
    
    var altPressed = evt.altKey ? true : false;
    if (altPressed)
    {
		for (var i = 0; i < numOfLayers; i++)
		{
			bringToLifeLayer(i);
		}
        return false;
    }
	
    for (var i = 0; i < numOfLayers; i++)
		layers[i].startDrag(evt);
		
	return false;
    
}

function handleKeyEvent(evt)
{
	evt = evt ? evt : event;
	if (evt)
	{
		var key = evt.keyCode;
		//var esc = (event) ? 27 : evt.DOM_VK_ESCAPE;
		if (key == 27)
		{
			hideAllPopups();
			cancelZoomToWindow();
//			if (zoominInArea)
//			{
//				zoominInArea = false;
//				swapVisibility("tZoomToRegion_over","tZoomToRegion");
//				document.body.style.cursor='move';
//			}
		}
		if (key == 46 && isVisible("browsePopup"))
		{
			var uploader = document.getElementById("logInViewCtrl1_Uploader");

			if (uploader)
				fileBrowser.deleteSelectedFile();
			else
				alert("You do not have permission to delete this file.");
		}
	}
}

// Drag an element
function doDrag(evt) 
{
	if (isVisible("fader") == true)
		return true;

    evt = (evt) ? evt : event;
    
    for (var i = 0; i < numOfLayers; i++)
	{
		if (layers[i])
			layers[i].doDrag(evt);
	}
	
	return false;
}

// Turn selected element off
function endDrag(evt) 
{
	if (isVisible("fader") == true)
		return true;

    evt = evt ? evt : event;
    
    for (var i = 0; i < numOfLayers; i++)
	{
		if (layers[i])
			layers[i].endDrag(evt);
	}
	
}

function zoomIt(evt)
{
    evt = evt ? evt : event;

	// if fader is visible, don't handle zoom events.
	if (isVisible("fader") == true)
	{
		if (isVisible("browsePopup") == true)
			fileBrowser.browseFile(evt);			
		return false;
	}
    
    for (var i = 0; i < numOfLayers; i++)
	{
		if (layers[i])
			layers[i].zoomIt(evt);
	}
}

function recaptureAfterZoom()
{
	switchLayer();
	layers[activeLayer].recalcLayerAfterZoom();
	
    for (var i = 0; i < numOfLayers; i++)
		layers[i].zoomStarted = false;
	
	zoomInOutMode = false;
	suspendPan = false;
}

// micell.
function CDivObj(divIn, x, y)
{
    this.element = divIn;
    this.divX = x;
    this.divY = y;
}

function CSelObj(objIn, evt)
{
    this.obj = objIn;
    
    if (evt.pageX) 
    {
        this.offsetX = evt.pageX - ((objIn.offsetLeft) ? 
                  objIn.offsetLeft : objIn.left);
        this.offsetY = evt.pageY - ((objIn.offsetTop) ? 
                  objIn.offsetTop : objIn.top);
    } 
    else if (typeof evt.clientX != "undefined") 
    {
        this.offsetX = evt.clientX - ((objIn.offsetLeft) ? 
                  objIn.offsetLeft : 0);
        this.offsetY = evt.clientY - ((objIn.offsetTop) ? 
                  objIn.offsetTop : 0);
    }
    
}

function CLayer(layerIndex, isActive)
{
    this.layerIndex = layerIndex;
    this.isActiveLayer = isActive;
    
    this.selectedObj = null;
    
    this.xRange = [];
    this.yRange = [];
    
    this.center = [];
    this.center["x"] = Math.round(wnWidth/2);
    this.center["y"] = Math.round(wnHeight/2);
    
    this.absOrigin = [];
    this.absOrigin["x"] = 0;
    this.absOrigin["y"] = 0;
    
    this.createdDivs = [];
    this.createdImgs = [];
    
    this.zoom = 1.0;
    this.zoomImg = 1.0; // the zoom level at which image was captured.
    
    this.zoomToWindowMode = false;
    this.zoomToWindowZoom = 1.0;

    this.selDivX = 0;
    this.selDivY = 0;

    this.timerId = null;

    this.zoomStarted = false;

    this.dragBoxDiv = null;
    this.dragBoxOrig = [];
    this.dragBoxStDiv = [];
    this.dragBoxEndDiv = [];

    this.currOffset = [];
    this.currOffset["x"] = Math.round(imgSize/2);
    this.currOffset["y"] = Math.round(imgSize/2);
    
    this.zoomOffset = [];
    this.currSize = imgSize;
    
    this.calcDivRange();
   	this.createDivs(true);
   	this.positionDivs();
    

}

CLayer.prototype.cancelZoomToWindow = function() 
{
	if (this.dragBoxDiv)
	{
		var stl = getStyle(this.dragBoxDiv);
		stl.visibility = "hidden";
		this.dragBoxDiv = null;
	}
}

// Set global reference to element being engaged and dragged
CLayer.prototype.setSelectedElem = function(evt) 
{
    this.selectedObj = null;
    var target = (evt.target) ? evt.target : evt.srcElement;
    if (!target.name || !target.src)
        return;
        
    var imgName = null;
    if (this.isActiveLayer)
		imgName = target.name;
	else
		imgName = this.createIdString(0,0);
		
    var selDiv = this.createdDivs[imgName];
    if (!selDiv)
        return;

    this.selectedObj = selDiv.element;
	var sel = new CSelObj(this.selectedObj,evt);
    this.selDivX = selDiv.divX;
    this.selDivY = selDiv.divY;
    this.currOffset["x"] = sel.offsetX;
    this.currOffset["y"] = sel.offsetY;
    
    return;
}

CLayer.prototype.isPtInsideDivBBox = function(elem, ptx, pty)
{
    var topLeftX = elem.offsetLeft ? elem.offsetLeft : elem.left;
    var topLeftY = elem.offsetTop ? elem.offsetTop : elem.top;
    
    var wd = elem.offsetWidth;
    var ht = elem.offsetHeight;
    
    var botRightX = topLeftX + wd;
    var botRightY = topLeftY + ht;
    
    if (topLeftX <= ptx && ptx <= botRightX && topLeftY <= pty && pty <= botRightY)
		return true;
		
	return false;

}

CLayer.prototype.getSelObj = function(evt)
{
	// first check if the evt directly gives this element.
    var target = (evt.target) ? evt.target : evt.srcElement;
    if (!zoomInOutMode && target.name && target.src)
    {
		var imgName = target.name;
		var selDiv = this.createdDivs[imgName];
		if (selDiv)
			return selDiv;
	}

	// if the layer is different than the top most layer
	// event will not give the correct div.
	// hence calculating such divs.
    var mouseX = (evt.pageX || evt.pageY) ? evt.pageX : evt.clientX;
    var mouseY = (evt.pageX || evt.pageY) ? evt.pageY : evt.clientY;
    if (zoomInOutMode)
	{
		mouseX = Math.round(wnWidth/2);
		mouseY = Math.round(wnHeight/2);
	}

    for (var obj in this.createdDivs)
    {
        var selDiv = this.createdDivs[obj];
        var currElem = selDiv.element;
        if (this.isPtInsideDivBBox(currElem,mouseX,mouseY) )
			return selDiv;
    }
    
    return null;

}
var prevZoom = 1;
CLayer.prototype.zoomIt = function(evt)
{
    evt = (evt) ? evt : event;
    
    if (this.zoomStarted == false)
    {
        this.zoomStarted = true;

		var selDiv = this.getSelObj(evt);      
		if (!selDiv)
			return;  

        this.selDivX = selDiv.divX;
        this.selDivY = selDiv.divY;
        this.currOffset["x"] = 0;
        this.currOffset["y"] = 0;
        
        var elem = selDiv.element;

	    var offX = elem.offsetLeft ? elem.offsetLeft : elem.left;
	    var offY = elem.offsetTop ? elem.offsetTop : elem.top;
	    
	    if (zoomInOutMode)
	    {
            prevClientX = Math.round(wnWidth/2);
            prevClientY = Math.round(wnHeight/2);
        }
        
	    this.center["x"] = prevClientX;
	    this.center["y"] = prevClientY;
	    
	    this.zoomOffset["x"] = this.center["x"] - offX;
	    this.zoomOffset["y"] = this.center["y"] - offY;

	    var divCenterX = offX + Math.round(this.currSize/2);
	    var divCenterY = offY + Math.round(this.currSize/2);
	    
	    this.absOrigin["x"] = this.selDivX + (this.center["x"] - divCenterX)/this.currSize;
	    this.absOrigin["y"] = this.selDivY + (this.center["y"] - divCenterY)/this.currSize;
		
		//dump("Zoom started - mousePt - " + prevClientX + "-x " + prevClientY + "-y ");
		//dump("selected divId-" +this.selDivX + " x " + this.selDivY + " y");
		//dump("currSize- " + this.currSize);
		prevZoom = this.zoom;
		
    }
    
    if (this.timerId)
        clearTimeout(this.timerId);        
        
    var delta = 0;

	if (zoomInOutMode)
	{
		if (zoomingIn)
			delta = 5;
		else
			delta = -5;
	}
	else
	{
	    if (evt.wheelDelta) 
	    {
	        delta = evt.wheelDelta/120;
	    } 
	    else if (evt.detail) 
	    {
	        delta = -evt.detail/3;
	    }
	}
	
	var newZoom = this.zoom;
    if (this.zoom > 5)
        newZoom += delta;
    else if (this.zoom > 2)
        newZoom += delta/2;
    else
        newZoom += delta/15;

	if (this.zoomToWindowMode)
		newZoom = this.zoomToWindowZoom;
        

    // +ve means up, -ve means down.
    if (delta && newZoom > 0.5 && newZoom < 200)
    {
		this.zoom = newZoom;

        //var relativeZoom = this.zoom/this.zoomImg;
		var relativeZoom = this.zoom/prevZoom;

        this.currOffset["x"] = Math.round(this.zoomOffset["x"]*relativeZoom);
        this.currOffset["y"] = Math.round(this.zoomOffset["y"]*relativeZoom);
		
		//dump("zoom offset " + this.zoomOffset["x"] + "x " + this.zoomOffset["y"] + "Y");
		//dump("currOffsetX and Y - " + this.currOffset["x"] + "x" + this.currOffset["y"] + "y");
		//dump("relative zoom " + relativeZoom);
        
        this.positionDivs();
        
        // set timer only for first layer. Don't need to set three timers.
        if (this.layerIndex == 0)
        {
			this.timerId = setTimeout(recaptureAfterZoom,1000);
			suspendPan = true;
		}
			
		if (!zoomInOutMode)
		{
	        if (evt.preventDefault)
	        {
	            evt.preventDefault();
	        }
		}
    
    }
    else
    {
		suspendPan = true;
		this.zoomStarted = false;
	}
    this.selectedObj = null;
    
	evt.returnValue = false;
	
	return false;
    
}

function recalcStatus()
{
	if (request.readyState == 4)
	{
		var retVal = request.responseText;
		//alert(retVal);
	}
}

CLayer.prototype.recalcLayerAfterZoom = function()
{
    // this function will center new images around absOrigin[] point in image space
    // and the center[] on the screen space.
    
    this.removeAllDivs();
    this.zoomImg = this.zoom;
    wnWidth = getViewportWidth();
    wnHeight = getViewportHeight();
    
    this.currOffset["x"] = Math.round(imgSize/2);
    this.currOffset["y"] = Math.round(imgSize/2);
    
    this.selDivX = 0;
    this.selDivY = 0;

    this.calcDivRange();
    
    var smaller = (wnWidth < wnHeight) ? wnWidth : wnHeight;
    //numVisDivs = Math.ceil(smaller/imgSize) + 1;
    
    // after zoom, we will need new timestamp.
   	newLayerTimeStamp = new Date().getTime();

	var request = getRequest();
	var url = "asynch.aspx?newlayer=" + true + "&zoom=" + this.zoomImg + "&ox=" + this.absOrigin["x"] + "&oy=" + this.absOrigin["y"] + "&ts=" + newLayerTimeStamp;
	request.open("GET",url,true);
	request.onreadystatechange = recalcStatus;
	request.send(null);
    
    this.createDivs(true);
   	this.positionDivs();
   	this.zoomStarted = false;
}


// Turn selected element on
CLayer.prototype.startDrag = function(evt) 
{
    evt = (evt) ? evt : event;
    
    var ctrlPressed = evt.ctrlKey ? true : false;
    if (ctrlPressed || zoominInArea)
    {
        return this.onMouseDownZTW(evt);
    }
    
    this.setSelectedElem(evt);
    if (this.selectedObj) 
    {
        if (document.body && document.body.setCapture) 
        {
            // engage event capture in IE/Win
            document.body.setCapture();
        }
        
        return false;
    }
}



// Drag an element
CLayer.prototype.doDrag = function(evt) 
{
    evt = (evt) ? evt : event;
    
    if (this.dragBoxDiv)
    {
        return this.onMouseMoveZTW(evt);
    }
    
    if (this.selectedObj) {
    
        this.center["x"] = evt.pageX ? evt.pageX : evt.clientX;
        this.center["y"] = evt.pageY ? evt.pageY : evt.clientY;
        this.calcDivRange();
        this.createDivs(false);

        this.positionDivs();
        
	    return false;
    }
    else
    {
        prevClientX = evt.pageX ? evt.pageX : evt.clientX;
        prevClientY = evt.pageY ? evt.pageY : evt.clientY;
    }
}

// Turn selected element off
CLayer.prototype.endDrag = function(evt) 
{
    evt = evt ? evt : event;
    
    if (this.dragBoxDiv)
    {
		zoominInArea = false;
		swapVisibility("tZoomToRegion_over","tZoomToRegion");
		document.body.style.cursor='move';

        return this.onMouseUpZTW(evt);
        
    }
    
    if (this.selectedObj) 
    {
        if (document.body && document.body.releaseCapture) 
        {
            // stop event capture in IE/Win
            document.body.releaseCapture();
        }
        this.selectedObj = null;

    }
}

CLayer.prototype.panByDelta = function(evt,xdir,ydir)
{
	evt = (evt) ? evt : event;
	
    var imgName = this.createIdString(0,0);
		
    var selDiv = this.createdDivs[imgName];
    if (!selDiv)
        return;

    this.selectedObj = selDiv.element;
	var sel = new CSelObj(this.selectedObj,evt);
    this.selDivX = selDiv.divX;
    this.selDivY = selDiv.divY;
    this.currOffset["x"] = sel.offsetX;
    this.currOffset["y"] = sel.offsetY;
    
    this.center["x"] = evt.pageX ? evt.pageX : evt.clientX;
    this.center["y"] = evt.pageY ? evt.pageY : evt.clientY;
	
	this.center["x"] += 200*xdir; 
	this.center["y"] += 200*ydir;
	
    this.calcDivRange();
    this.createDivs(false);

    this.positionDivs();
	
	this.selectedObj = null;
	
}

CLayer.prototype.moveBy = function(dx,dy)
{
    for (var obj in this.createdDivs)
    {
        var elemObj = this.createdDivs[obj];
        var currElem = elemObj.element;
        moveByPx(currElem,dx,dy);
      }

}

CLayer.prototype.onMouseDownZTW = function(evt)
{
    evt = (evt) ? evt : event;
    
    // setup the drag box, by making it visible, and setting
    // the top left point to the mouse click point.
    this.dragBoxDiv = getElement("dragBox");
    var stl = getStyle(this.dragBoxDiv);
    stl.visibility = "visible";
    this.dragBoxOrig["x"] = evt.pageX ? evt.pageX : evt.clientX;
    this.dragBoxOrig["y"] = evt.pageY ? evt.pageY : evt.clientY;

    this.dragBoxOrig["x"] -= 11;
    this.dragBoxOrig["y"] -= 15;
    
    stl.left = "" + this.dragBoxOrig["x"] + "px";
    stl.top = "" + this.dragBoxOrig["y"] + "px";
    stl.width = "" + 0 + "px";
    stl.height = "" + 0 + "px";
    
    return;    
}

CLayer.prototype.onMouseMoveZTW = function(evt)
{
    evt = (evt) ? evt : event;

    if (!this.dragBoxDiv)
        return false;
    
    var stl = getStyle(this.dragBoxDiv);
    
    var xpos = evt.pageX ? evt.pageX : evt.clientX;
    var ypos = evt.pageY ? evt.pageY : evt.clientY;
    
    xpos -= 11;
    ypos -= 15;
    
    var newWidth = xpos - this.dragBoxOrig["x"];
    var newHeight = ypos -  this.dragBoxOrig["y"];
    
    var aspectRatio = wnWidth/wnHeight;
    
    var tempWd = Math.round(newHeight*aspectRatio);
    var tempHt = Math.round(newWidth/aspectRatio);
    
	if (tempHt > newHeight)
		newHeight = tempHt;
	if (tempWd > newWidth)
		newWidth = tempWd;

	if (newWidth > 0)
		stl.width = "" + newWidth + "px";
    
    if (newHeight > 0)
		stl.height = "" + newHeight + "px";
    return false;
}

CLayer.prototype.onMouseUpZTW = function(evt)
{
    evt = (evt) ? evt : event;
    if (!this.dragBoxDiv)
        return;
        
    var currHt = getElementHeight(this.dragBoxDiv);
    var currWd = getElementWidth(this.dragBoxDiv);
    
    if (currHt < 15 || currWd < 15)
    {
		// first make the box invisible. its job is done.
		cancelZoomToWindow();
		this.cancelZoomToWindow();
		return;
	}
    
    var currCenterX = this.dragBoxOrig["x"] + Math.round(currWd/2);
    var currCenterY = this.dragBoxOrig["y"] + Math.round(currHt/2);
    var scrCenterX = Math.round(wnWidth/2);
    var scrCenterY = Math.round(wnHeight/2);
    
    var dx = scrCenterX - currCenterX;
    var dy = scrCenterY - currCenterY;
    
    // first make the box invisible. its job is done.
    var stl = getStyle(this.dragBoxDiv);
    stl.visibility = "hidden";
    this.dragBoxDiv = null;
    
	this.moveBy(dx,dy);
	
	this.zoomToWindowMode = true;
	zoomInOutMode = true;

	this.zoomToWindowZoom = (this.zoom * wnWidth / currWd);
	if (this.zoomToWindowZoom > 200)
		this.zoomToWindowZoom = 200;
	else if (this.zoomToWindowZoom > 10)
		this.zoomToWindowZoom *= 0.9;
	
	this.zoomIt(evt);
	
	this.zoomToWindowMode = false;
	zoomInOutMode = false;

    return false;    
}

CLayer.prototype.createDivs = function(recalc)
{
	// this is a special case, when user directory has no files at all.
	if (isBlankDir == true)
		return;
	
	if (!this.isActiveLayer)
		return;

    for (var yIndex = this.yRange[0]; yIndex < this.yRange[1]; yIndex++)
    {
        for (var xIndex = this.xRange[0] ; xIndex < this.xRange[1]; xIndex++)
        {
            // only create stuff if they don't exist already
            var idStr = this.createIdString(xIndex,yIndex);
            if (recalc || !this.createdDivs[idStr])
            {
                this.createOneDiv(xIndex,yIndex);
            }
        }
    }
}

CLayer.prototype.createOneDiv = function(x, y)
{
	if (!this.isActiveLayer)
		return;
		
    if (x < this.xRange[0] || x > this.xRange[1] || y < this.yRange[0] || y > this.yRange[1])
        return false;
        
    var imgName = this.createImgName(x,y);
   
    var elemObj = this.createdDivs[imgName];
    if (elemObj)
    {
        var elem = elemObj.element;
        
        var img = elem.getElementsByTagName('img')[0];
        var srStr = createSrcString(x,y);
        img.setAttribute("src", srStr);
        img.setAttribute("height", imgSize);
        img.setAttribute("width", imgSize);
    }
    else
    {
        var elem = document.createElement("div");
        
        var divId = this.createDivId(x,y);
        elem.setAttribute("id",divId);
        elem.setAttribute("class","drggable");
        
        var img = document.createElement("img");

        var srStr = this.createSrcString(x,y);
        img.setAttribute("src", srStr);
        img.setAttribute("height", imgSize);
        img.setAttribute("width", imgSize);
        img.setAttribute("alt", "");
        img.setAttribute("name", imgName);
        this.createdImgs[imgName] = img;
        
        elem.appendChild(img);
        
        var parentElem = getElement("clientSideImgs");
        parentElem.appendChild(elem);
        //document.body.appendChild(elem);
        this.createdDivs[imgName] = new CDivObj(elem,x,y);
    }
    return true;
    
}

CLayer.prototype.removeAllDivs = function()
{
	
    for (var obj in this.createdDivs)
    {
        var elemObj = this.createdDivs[obj];
        var currElem = elemObj.element;
        var parentElem = getElement("clientSideImgs");
        parentElem.removeChild(currElem);
//        document.body.removeChild(currElem);
    }
    
    this.createdDivs = new Array();
    this.createdImgs = new Array();
}

CLayer.prototype.positionDivs = function()
{
    var relativeZoom = this.zoom/this.zoomImg;
    this.currSize = Math.round(imgSize*relativeZoom);
    var xOffset = this.currOffset["x"];
    var yOffset = this.currOffset["y"];

    //var currCycleIndex = "" + cycleIndex + "cycleIndex";
    for (var obj in this.createdDivs)
    {
        //if (obj.indexOf(currCycleIndex) == -1)
        //    continue;
            
        var elemObj = this.createdDivs[obj];
        var xIndex = elemObj.divX;
        var yIndex = elemObj.divY;
        var currElem = elemObj.element;

      
        var xPos = this.center["x"] + (xIndex-this.selDivX)*this.currSize - xOffset;
        var yPos = this.center["y"] + (yIndex-this.selDivY)*this.currSize - yOffset;
        var elemStyle = getStyle(currElem);
        elemStyle.position = "absolute";
        
        if (this.currSize != imgSize)
        {
            var idStr = this.createIdString(xIndex,yIndex);
            var img = this.createdImgs[idStr];
            img.setAttribute("height", this.currSize);
            img.setAttribute("width", this.currSize);
        }
        
        moveToPx(currElem, xPos, yPos);
		//dump("div xIndex " + xIndex + " yIndex " + yIndex + " xPos " + xPos + " yPos "+ yPos);
      }
}


CLayer.prototype.createIdString = function(x,y)
{
    var idStr = "" + x + "x" + y + "y";
    return idStr;
}

CLayer.prototype.createDivId = function(x,y)
{
    var str = this.createIdString(x,y);
    str = str + "-div" ;
    return str;
}

CLayer.prototype.createImgName = function(x,y)
{
    return this.createIdString(x,y);
}

CLayer.prototype.createSrcString = function(x,y)
{
    var str = "default.aspx?file=" + fileName + "&zoom=" + this.zoomImg + "&dx=" + x + "&dy=" + y + "&ox=" + this.absOrigin["x"] + "&oy=" + this.absOrigin["y"] + "&vd=" + numVisDivs + "&sheet=" + selectedSheetIndex + "&ts=" + newLayerTimeStamp;
    return str;
}

CLayer.prototype.calcDivRange = function()
{
	if (!this.isActiveLayer)
		return;
		
    this.xRange[0] = (-1*( Math.ceil( this.center["x"]/imgSize + 0.5)/* + 1*/)) + 1+ this.selDivX;
    this.xRange[1] = Math.ceil( (wnWidth - this.center["x"])/imgSize + 0.5) + this.selDivX + 1;

    // keeping up direction of Y as positive.
    this.yRange[0] = (-1*( Math.ceil( this.center["y"]/imgSize + 0.5)/* + 1*/)) + 1 + this.selDivY;
    this.yRange[1] = Math.ceil( (wnHeight - this.center["y"])/imgSize +0.5) + this.selDivY + 1;
}
