"use strict";

module("CSLEDIT.controller", {
	setup : function () {
		CSLEDIT.controller.clearHistory();
		CSLEDIT.data = new CSLEDIT.Data("CSLEDIT.test_cslData");
	}
});

test("cslData must contain all the commands", function () {
	raises( function () {
		CSLEDIT.controller.setCslData({});
	});
});

test("can only call actual commands and macros", function () {
	CSLEDIT.controller.setCslData(CSLEDIT.data);

	CSLEDIT.controller.setCslData({
		addNode : function () {},
		deleteNode : function () {},
		moveNode : function () {},
		amendNode : function () {},
		setCslCode : function () {},
	});

	CSLEDIT.controller.exec("addNode");

	raises( function () {
		CSLEDIT.controller.exec("noSuchCommand");
	});
});
		
test("test exec", function () {
	var temp;

	var addToTemp = function (increment1, increment2) {
		temp += increment1 + increment2;
	};

	temp = 3;
	CSLEDIT.controller.setCslData({
		addNode : addToTemp,
		deleteNode : function () {},
		moveNode : function () {},
		amendNode : function () {},
		setCslCode : function () {},
	});

	CSLEDIT.controller.exec("addNode", [4, 5]);
	equal(temp, 12);
});

test("undo", function () {
	// undo requires CSLEDIT.data to return the inverse function
	// for every function that's called

	var lastCommand;

	CSLEDIT.controller.setCslData({
		addNode : function (arg) {
			lastCommand = "addNode(" + arg + ")";
			// return inverse of addNode(id)
			return {
				command : "deleteNode",
				args : [arg]
			}
		},
		deleteNode : function (arg) {
			lastCommand = "deleteNode(" + arg + ")";
		},
		moveNode : function () {},
		amendNode : function () {},
		setCslCode : function () {},
	});

	CSLEDIT.controller.exec("addNode", [1]);
	equal(lastCommand, "addNode(1)");
	CSLEDIT.controller.exec("addNode", [2]);
	equal(lastCommand, "addNode(2)");

	CSLEDIT.controller.undo();
	equal(lastCommand, "deleteNode(2)");
	CSLEDIT.controller.undo();
	equal(lastCommand, "deleteNode(1)");

	equal(CSLEDIT.controller.commandHistory.length, 0);
});

@@ -1120,16 +1120,23 @@
 st(%22undo
+ / redo
 %22, funct
@@ -1144,16 +1144,16 @@
 on () %7B%0A
-
 %09// undo
@@ -1545,16 +1545,96 @@
  + %22)%22;%0A
+%09%09%09// return inverse%0A%09%09%09return %7B%0A%09%09%09%09command : %22addNode%22,%0A%09%09%09%09args : %5Barg%5D%0A%09%09%09%7D%0A
 %09%09%7D,%0A%09%09m
@@ -1877,24 +1877,136 @@
 Node(2)%22);%0A%0A
+%09// the view can do this check to see if undo is possible%0A%09equal(CSLEDIT.controller.commandHistory.length, 2);%0A%0A
 %09CSLEDIT.con
@@ -2126,16 +2126,41 @@
 (1)%22);%0A%0A
+%09// nothing more to undo%0A
 %09equal(C
@@ -2201,15 +2201,596 @@
 ength, 0
+, %22no more undos left%22);%0A%0A%09// the view can do this check to see if redo is possible%0A%09equal(CSLEDIT.controller.undoCommandHistory.length, 2, %222 redos possible%22);%0A%09CSLEDIT.controller.redo();%0A%09equal(lastCommand, %22addNode(1)%22, %22redo performed: addNode(1)%22);%0A%0A%09// one more redo possible%0A%09equal(CSLEDIT.controller.undoCommandHistory.length, 1, %221 redo possible%22);%0A%0A%09// perfoming any new command resets the undoCommandHistory%0A%09CSLEDIT.controller.exec(%22addNode%22, %5B4%5D);%0A%0A%09// no redos allowed (need to undo again first)%0A%09equal(CSLEDIT.controller.undoCommandHistory.length, 0, %22no more redos%22
 );%0A%7D);%0A

Add unit test for redo