
// xcalc.js
// Script to interact with xThink Calculator program
// copyright xThink 2007
// This code is the property of xThink.

window.onload = function() {
	init();
}

// the 2d drawing context
var calcCtx;

var savedCtx;

var drawing = false;

var lastrecognized = "";


/**
 * Drawing functions
 */

function transform_event_coord(e) {
	return {
		x: Event.pointerX(e) - calcCtx.canvasOffsets[0], y: Event.pointerY(e) - calcCtx.canvasOffsets[1]
	};
}

function on_mousedown(e) {
	var pos = transform_event_coord(e);
	if (pos.x < 0 || pos.x > 600 || pos.y < 0 || pos.y > 400)
		return;
	drawing = true;
	resetLastRecognized();
  calcCtx.openStrokeSequence(pos, colorButtonPicker.getSelectedValue());
}

function on_mousemove(e) {
	if (!drawing) return;
	var pos = transform_event_coord(e);
	if (pos.x < 0 || pos.x > 600 || pos.y < 0 || pos.y > 400) return;
	calcCtx.addStroke(pos);
}

function on_mouseup(e) {
	if (!drawing) return;
	drawing = false;
	calcCtx.closeStrokeSequence();
}


/**
 * Save, restore, and clear
 */

function restore(event) {
	Event.stop(event);
	var clickedId = Event.findElement(event, "div").getAttribute("id");
	var savedCtx = savedCanvases[clickedId];
	if (savedCtx) {
		calcCtx.copyFrom(savedCtx);
		resetLastRecognized();
	}
}

function save() {
	var slot = savedSlotPicker.getSelectedValue();
	var savedCtx = savedCanvases[slot];
	savedCtx.copyFrom(calcCtx);
	if (lastrecognized == "") {
		$(slot).down("span").update("(not solved)");
	} else {
		$(slot).down("span").update(lastrecognized);
	}
}

function undo() {
	resetLastRecognized();
	calcCtx.removeLastStrokeSequence();
	calcCtx.setStrokeStyle(colorButtonPicker.getSelectedValue());
	calcCtx.setFillStyle(colorButtonPicker.getSelectedValue());
}

function clearCanvas() {
	resetLastRecognized();
	calcCtx.clear();
}

updateLastRecognized = function(transport, params) {
	lastrecognized = transport.responseText;
	enableFeedback();
}

function resetLastRecognized() {
	lastrecognized = "";
	$("solution").update("Ready");
	disableFeedback();
}

function enableFeedback() {
	$("ratingPanel").show();
}

function disableFeedback(){
	$("ratingPanel").hide();
}

/**
 * Event handlers that interact with the server via AJAX
 */
 
function on_solveButtonClick() {
	var s = calcCtx.createRecognizerInput();
	if (s == "") {
		alert("There is no input to solve!");
		return;
	}
	var url = "xcalc.asp";
	var param = preparePacketString("q", s);
	new Ajax.Updater("solution", url, {onComplete: updateLastRecognized, method: 'post', parameters: param});
}

function on_positiveFeedback() {
	var url = "feedback.asp";
	var packet = preparePacketString("q", calcCtx.createRecognizerInput());
	var recognized = "recognized=" + escape(lastrecognized);
	var correct = "iscorrect=true";
	var param = packet + "&" + recognized + "&" + correct;
	new Ajax.Updater("solution", url, {method: 'post', parameters: param});
}

function on_negativeFeedback() {
	var msg = createNegativeFeedbackMsg(lastrecognized);
	feedbackDialog.setContent(msg);
	feedbackDialog.show();
}

function on_correctingFeedbackSubmit(txt) {
	var url = "feedback.asp";
	var packet = preparePacketString("q", calcCtx.createRecognizerInput());
	var recognized = "recognized=" + escape(lastrecognized);
	var correct = "iscorrect=false";
	var proposed = "proposed=" + escape(txt);
	var param = packet + "&" + recognized + "&" + correct + "&" + proposed;
	new Ajax.Updater("solution", url, {method: 'post', parameters: param});
	feedbackDialog.hide();
}

function on_help() {
	var msg = createHelpDialog();
	helpDialog.setContent(msg);
	helpDialog.show();
}


function on_termsOfService() {
	var msg = createTermsOfServiceMsg();
	termsOfServiceDialog.setContent(msg);
	termsOfServiceDialog.show();
}




/**
 * Utility functions
 */
 
function preparePacketString(param, strokes) {
	var isDegree = degradButtonPicker.getSelectedValue() == "deg" ? 1 : 0;
	var precision = precisionButtonPicker.getSelectedValue();
	var result = param + "=<packet>";
	result += "<strokes>" + strokes + "</strokes>";
	result += "<degree>" + isDegree + "</degree>";
	result += "<precision>" + precision + "</precision>";
	result += "</packet>";
	return result;
}
 

/**
 * Initializing functions
 */

function createSaveSlots() {
	savedCanvases = new Array();
	for (var i = 1; i <= 4; i++) {
		// create div
		var divId = "savedslot0" + i;
		var divEl = document.createElement('div');
		Element.extend(divEl);
		divEl.setAttribute("id", divId);
		divEl.addClassName("savedslot");
		
		// create action elements
		var restoreAnchorEl = document.createElement('a');
		Element.extend(restoreAnchorEl);
		restoreAnchorEl.setAttribute("href", "javascript:void(0)");
		restoreAnchorEl.update("Restore");
		Event.observe(restoreAnchorEl, "click", restore, false);
		
		// create canvas
		var canvasId = "savedcanvas0" + i;
		var canvasEl = document.createElement('canvas');
		canvasEl.setAttribute("width", 200);
		canvasEl.setAttribute("height", 100);
		canvasEl.id = canvasId;

		// create recognized status line
		var recognizedEl = document.createElement('span');
		Element.extend(recognizedEl);
		recognizedEl.setAttribute("id", "recognized0" + i);
		recognizedEl.addClassName("recognized");
		
		$("saved").appendChild(divEl);
		
		// insert div + canvas
		$(divId).appendChild(restoreAnchorEl);
		$(divId).appendChild(canvasEl);

		// IE workaround		
		if (typeof G_vmlCanvasManager != "undefined") {
			G_vmlCanvasManager.initElement(canvasEl);
		}
		Element.extend(canvasEl);
		
		// insert action elements
		$(divId).appendChild(recognizedEl);
		
		// create restorablecontext based on the canvas
		var saveCtx = new RestorableContext($(canvasId));
		//saveCtx.setScale(0.25, 0.25);
		saveCtx.setScale(0.25, 0.25);
		savedCanvases[divId] = saveCtx;
	}
}

function createFeedbackPanel() {
	var ratingPanel = document.createElement("div");
	Element.extend(ratingPanel);
	ratingPanel.setAttribute("id", "ratingPanel");
	
	var anchorYes = document.createElement("a");
	Element.extend(anchorYes);
	anchorYes.setAttribute("href", "javascript:void(0)");
	anchorYes.setAttribute("title", "Click here if your strokes were recognized correctly.");
	anchorYes.update("Yes");
	Event.observe(anchorYes, "click", on_positiveFeedback, false);

	var anchorNo = document.createElement("a");
	Element.extend(anchorNo);
	anchorNo.setAttribute("href", "javascript:void(0)");
	anchorNo.setAttribute("title", "Click here if you want to suggest a different solution.");
	anchorNo.update("No");
	Event.observe(anchorNo, "click", on_negativeFeedback, false);
	
	$("solutionbox").insertBefore(ratingPanel, $("solution"));
	$("ratingPanel").appendChild(document.createTextNode("Correct? "));
	$("ratingPanel").appendChild(anchorYes);
	$("ratingPanel").appendChild(document.createTextNode(" "));
	$("ratingPanel").appendChild(anchorNo);
	disableFeedback();
}



initCoords = function() {
	calcCtx.initCoords();
}

function initializeCalcContext() {
	calcCtx = new RestorableContext($("calc"));
	calcCtx.setStrokeStyle("black");
	calcCtx.setFillStyle("black");
	calcCtx.setLineWidth(2);
	calcCtx.setLineJoin("miter");
	Event.observe(window, 'resize', initCoords);
}

function initializeDrawingEventHandlers() {
	Event.observe($("calc"), 'mousedown', on_mousedown);
	Event.observe($("calc"), 'mousemove', on_mousemove);
	Event.observe(document, 'mouseup', on_mouseup);
}

colorChangeCallback = function() {
	calcCtx.setStrokeStyle(colorButtonPicker.getSelectedValue());
	calcCtx.setFillStyle(colorButtonPicker.getSelectedValue());
};


/**
 * Pickers
 */

var precisionButtonPicker;
var degradButtonPicker;
var savedSlotPicker;

function initializePickers() {
	degradButtonPicker = new Picker();
	degradButtonPicker.setClassToHandle("degradbutton");
	degradButtonPicker.setValues(
		{ 'degbutton' : 'deg',
		  'radbutton' : 'rad'
		}
	);
	degradButtonPicker.selectValue('deg');
	
	precisionButtonPicker = new Picker();
	precisionButtonPicker.setClassToHandle("precisionbutton");
	precisionButtonPicker.setValues(
		{'precisionbutton01' : 1,
		 'precisionbutton02' : 2,
		 'precisionbutton03' : 3,
     'precisionbutton04' : 4,
		 'precisionbutton05' : 5,
		 'precisionbutton06' : 6,
		 'precisionbutton07' : 7,
		 'precisionbutton08' : 8,
		 'precisionbutton09' : 9
		}
	);
	precisionButtonPicker.selectValue(9);

	colorButtonPicker = new Picker();
	colorButtonPicker.setClassToHandle("colorbutton");
	colorButtonPicker.setValues(
		{'colorbutton00' : '#000',
		 'colorbutton01' : '#FF0',
		 'colorbutton02' : '#F0F',
		 'colorbutton03' : '#0FF',
		 'colorbutton04' : '#F00',
		 'colorbutton05' : '#0F0',
		 'colorbutton06' : '#00F'
		}
	);
	colorButtonPicker.setChangeCallback(colorChangeCallback);
	colorButtonPicker.selectValue('#000');

	savedSlotPicker = new Picker();
	savedSlotPicker.setClassToHandle("savedslot");
	savedSlotPicker.setValues(
		{'savedslot01' : 'savedslot01',
		 'savedslot02' : 'savedslot02',
		 'savedslot03' : 'savedslot03',
		 'savedslot04' : 'savedslot04',
		 'savedslot05' : 'savedslot05'
		}
	);
	savedSlotPicker.selectValue('savedslot01');
}


/**
 * Initialization that is called onload
 */
 
function init() {

	initializeCalcContext();
	
	initializeDrawingEventHandlers();
	
	createSaveSlots();
	
	initializePickers();
	
	createFeedbackPanel();

	feedbackDialog = new ModalDialog("feedback", "feedbackDialog");	
	
	termsOfServiceDialog = new ModalDialog("termsOfService", "termsOfServiceDialog");
	
	helpDialog = new ModalDialog("help", "helpDialog");
}


