// Copyright 2008 ProjectWizards GmbH. All rights reserved.

var tests = {

	run: function(){
	    var TestRunner = YAHOO.tool.TestRunner; 
		TestRunner.clear();
		var testSuites = this.testSuites();
		for(var i=0; i<testSuites.length; i++)
			TestRunner.add(testSuites[i]);
		function handleTestFail(data){ 
	        console.log("Test named '" + data.testName + "' failed with message: '" + data.error.message + "'."); 
	    } 
	    TestRunner.subscribe(TestRunner.TEST_FAIL_EVENT, handleTestFail); 
		TestRunner.run();				
	},

	testSuites: function() {
		var testSuites = [];
		var suite;
		
		/* ---------------- BudgetFormatter (which also tests CurrencyFormatter and PercentFormatter) ---------------- */

		suite = new YAHOO.tool.TestSuite("BudgetFormatter");
		testSuites.push(suite);

		suite.addCurrencySymbol = function(amountString) {
				if(environment.currencySymbolBeforeAmount)
					return environment.currencySymbol+" "+amountString;
				return amountString+" "+environment.currencySymbol;
		}

		suite.add( new YAHOO.tool.TestCase({
			
			name: "stringForObjectValue",
			
			setUp: function() {
				this.formatter = new BudgetFormatter(environment);
			},
			
			tearDown: function() {
				delete this.formatter;
			},
	
			testBudgetFormatter_StringForObjectValue_percent: function() {
				var Assert = YAHOO.util.Assert;
				Assert.areEqual("-10 %", this.formatter.stringForObjectValue(new MEBudget({a:-0.1, f:true})));
				Assert.areEqual("0 %", this.formatter.stringForObjectValue(new MEBudget({a:0, f:true})));
				Assert.areEqual("50 %", this.formatter.stringForObjectValue(new MEBudget({a:0.5, f:true})));
				Assert.areEqual("100 %", this.formatter.stringForObjectValue(new MEBudget({a:1.0, f:true})));
				Assert.areEqual("200 %", this.formatter.stringForObjectValue(new MEBudget({a:2.0, f:true})));
			},

			testBudgetFormatter_StringForObjectValue_currency: function() {
				var Assert = YAHOO.util.Assert;
				var decimalSeparator = environment.decimalSeparator;
				var thousandSeparator = environment.thousandSeparator;
				Assert.areEqual("", this.formatter.stringForObjectValue(new MEBudget({a:0, f:false})));
				Assert.areEqual(suite.addCurrencySymbol("99"+decimalSeparator+"00"), this.formatter.stringForObjectValue(new MEBudget({a:99, f:false})));
				Assert.areEqual(suite.addCurrencySymbol("100"+decimalSeparator+"00"), this.formatter.stringForObjectValue(new MEBudget({a:100, f:false})));
				Assert.areEqual(suite.addCurrencySymbol("100"+decimalSeparator+"56"), this.formatter.stringForObjectValue(new MEBudget({a:100.5555, f:false})));
				Assert.areEqual(suite.addCurrencySymbol("100"+thousandSeparator+"000"+thousandSeparator+"000"+decimalSeparator+"12"), this.formatter.stringForObjectValue(new MEBudget({a:100000000.123, f:false})));
				Assert.areEqual(suite.addCurrencySymbol("150"+thousandSeparator+"000"+decimalSeparator+"00"), this.formatter.stringForObjectValue(new MEBudget({a:150000.00, f:false})));
			}
		})); 

		suite.add( new YAHOO.tool.TestCase({
			
			name: "objectValueForString",
			
			setUp: function() {
				this.formatter = new BudgetFormatter(environment);
			},
			
			tearDown: function() {
				delete this.formatter;
			},
	
			assertAreEqual: function(budget, amount, isFractional) {
				var Assert = YAHOO.util.Assert;
				Assert.areEqual(amount, budget.amount);
				Assert.areEqual(isFractional, budget.isFractional);			
			},
			
			testBudgetFormatter_ObjectValueForString_percent: function() {
				this.assertAreEqual(this.formatter.objectValueForString("-10 %"), -0.1, true);
				this.assertAreEqual(this.formatter.objectValueForString("0 %"), 0, true);
				this.assertAreEqual(this.formatter.objectValueForString("50 %"), 0.5, true);
				this.assertAreEqual(this.formatter.objectValueForString("100 %"), 1, true);
				this.assertAreEqual(this.formatter.objectValueForString("200 %"), 2, true);
			},

			testBudgetFormatter_ObjectValueForString_currency: function() {
				var decimalSeparator = environment.decimalSeparator;
				var thousandSeparator = environment.thousandSeparator;
				this.assertAreEqual(this.formatter.objectValueForString(suite.addCurrencySymbol("100"+thousandSeparator+"000"+thousandSeparator+"000"+decimalSeparator+"12")), 100000000.12, false);
			}
		})); 


		/* ---------------- DurationFormatter ---------------- */

		suite = new YAHOO.tool.TestSuite("DurationFormatter");
		testSuites.push(suite);

		suite.addCurrencySymbol = function(amountString) {
				if(environment.currencySymbolBeforeAmount)
					return environment.currencySymbol+" "+amountString;
				return amountString+" "+environment.currencySymbol;
		}

		suite.add( new YAHOO.tool.TestCase({
			
			name: "stringForObjectValue",
			
			setUp: function() {
				this.formatter = new DurationFormatter(environment);
			},
			
			tearDown: function() {
				delete this.formatter;
			},
	
			testDurationFormatter_StringForObjectValue: function() {
				var Assert = YAHOO.util.Assert;
				var Units = MEDuration.DurationUnit;				
				var short;
				var plural;
				for(plural=0; plural<2; plural++) {
					var amount = plural ? 2 : 1;
					var amountString = ""+amount;
					for(short=0; short<2; short++) {
						this.formatter.setPreferedWidth(short ? 50 : 100);
						for(var isFloating=0; isFloating<2; isFloating++) {
							Assert.areEqual(amountString+(short?"":" ")+environment.localizedString((isFloating ? "e" : "")+"second"+(plural?"s":"")+(short ? "3" : "")), this.formatter.stringForObjectValue(new MEDuration({a:amount, u:Units.MESeconds, f:isFloating, e:0})));
							Assert.areEqual(amountString+(short?"":" ")+environment.localizedString((isFloating ? "e" : "")+"minute"+(plural?"s":"")+(short ? "3" : "")), this.formatter.stringForObjectValue(new MEDuration({a:amount, u:Units.MEMinutes, f:isFloating, e:0})));
							Assert.areEqual(amountString+(short?"":" ")+environment.localizedString((isFloating ? "e" : "")+"hour"+(plural?"s":"")+(short ? "3" : "")), this.formatter.stringForObjectValue(new MEDuration({a:amount, u:Units.MEHours, f:isFloating, e:0})));
							Assert.areEqual(amountString+(short?"":" ")+environment.localizedString((isFloating ? "e" : "")+"day"+(plural?"s":"")+(short ? "3" : "")), this.formatter.stringForObjectValue(new MEDuration({a:amount, u:Units.MEDays, f:isFloating, e:0})));
							Assert.areEqual(amountString+(short?"":" ")+environment.localizedString((isFloating ? "e" : "")+"week"+(plural?"s":"")+(short ? "3" : "")), this.formatter.stringForObjectValue(new MEDuration({a:amount, u:Units.MEWeeks, f:isFloating, e:0})));
							Assert.areEqual(amountString+(short?"":" ")+environment.localizedString((isFloating ? "e" : "")+"month"+(plural?"s":"")+(short ? "3" : "")), this.formatter.stringForObjectValue(new MEDuration({a:amount, u:Units.MEMonths, f:isFloating, e:0})));
							Assert.areEqual(amountString+(short?"":" ")+environment.localizedString((isFloating ? "e" : "")+"year"+(plural?"s":"")+(short ? "3" : "")), this.formatter.stringForObjectValue(new MEDuration({a:amount, u:Units.MEYears, f:isFloating, e:0})));
							if(!plural) {
								var relativeError = isFloating;
								Assert.areEqual("-10"+(short ? "%" : " %")+(relativeError ? (short ? "?" : " ?") : ""), this.formatter.stringForObjectValue(new MEDuration({a:-0.1, u:Units.MEFraction, f:false, e:relativeError})));
								Assert.areEqual("0"+(short ? "%" : " %")+(relativeError ? (short ? "?" : " ?") : ""), this.formatter.stringForObjectValue(new MEDuration({a:0, u:Units.MEFraction, f:false, e:relativeError})));
								Assert.areEqual("50"+(short ? "%" : " %")+(relativeError ? (short ? "?" : " ?") : ""), this.formatter.stringForObjectValue(new MEDuration({a:0.5, u:Units.MEFraction, f:false, e:relativeError})));
								Assert.areEqual("100"+(short ? "%" : " %")+(relativeError ? (short ? "?" : " ?") : ""), this.formatter.stringForObjectValue(new MEDuration({a:1, u:Units.MEFraction, f:false, e:relativeError})));
								Assert.areEqual("200"+(short ? "%" : " %")+(relativeError ? (short ? "?" : " ?") : ""), this.formatter.stringForObjectValue(new MEDuration({a:2, u:Units.MEFraction, f:false, e:relativeError})));
							}
						}
					}
				}
			},

			assertDurationIsEqual: function(duration, amount, unit, isFloating, relativeError, string) {
				var message = stringWithFormat('%s != (actual/expected) amount:(%f, %f) unit:(%d, %d) isFloating:(%d, %d) relativeError:(%f, %f)', string, duration.amount, amount, unit, duration.unit, duration.isFloating, isFloating, duration.relativeError, relativeError);
				var Assert = YAHOO.util.Assert;
				var Units = MEDuration.DurationUnit;				
				Assert.areEqual(amount, duration.amount, message);
				Assert.areEqual(unit, duration.unit, message);			
				Assert.areEqual(isFloating, duration.isFloating, message);
				Assert.areEqual(relativeError, duration.relativeError, message);
			},
			
			string: function(amount, baseString, isFloating, plural, relativeError, short) {
				var floatingString = isFloating ? "e" : "";
				var pluralString = plural ? "s" : "";
				var errorString = (relativeError ? (short ? "?" : " ?") : "");
				var shortSpaceString = short ? "" : " ";
				var shortThreeString = short ? "3" : "";
				return ""+amount+shortSpaceString+environment.localizedString(floatingString+baseString+pluralString+shortThreeString)+errorString;
			},
			
			percentString: function(baseString, short, relativeError) {
				return baseString+(short ? "%" : " %")+(relativeError ? (short ? "?" : " ?") : "");
			},
			
			testDurationFormatter_ObjectValueForString: function() {
				var Assert = YAHOO.util.Assert;
				var Units = MEDuration.DurationUnit;				
				var short;
				var plural;
				var relativeError;
				for(relativeError=0; relativeError<2; relativeError++) {
					for(plural=0; plural<2; plural++) {
						var amount = plural ? 2 : 1;
						for(short=0; short<2; short++) {
							this.formatter.setPreferedWidth(short ? 50 : 100);
							for(var isFloating=0; isFloating<2; isFloating++) {
								var string = this.string(amount, 'second', isFloating, plural, relativeError, short)			
								this.assertDurationIsEqual( this.formatter.objectValueForString(string), amount, Units.MESeconds, isFloating, relativeError, string);
								var string = this.string(amount, 'minute', isFloating, plural, relativeError, short)			
								this.assertDurationIsEqual( this.formatter.objectValueForString(string), amount, Units.MEMinutes, isFloating, relativeError, string);
								string = this.string(amount, 'hour', isFloating, plural, relativeError, short)			
								this.assertDurationIsEqual( this.formatter.objectValueForString(string), amount, Units.MEHours, isFloating, relativeError, string);
								string = this.string(amount, 'day', isFloating, plural, relativeError, short)			
								this.assertDurationIsEqual( this.formatter.objectValueForString(string), amount, Units.MEDays, isFloating, relativeError, string);
								string = this.string(amount, 'week', isFloating, plural, relativeError, short)			
								this.assertDurationIsEqual( this.formatter.objectValueForString(string), amount, Units.MEWeeks, isFloating, relativeError, string);
								string = this.string(amount, 'month', isFloating, plural, relativeError, short)			
								this.assertDurationIsEqual( this.formatter.objectValueForString(string), amount, Units.MEMonths, isFloating, relativeError, string);
								string = this.string(amount, 'year', isFloating, plural, relativeError, short)			
								this.assertDurationIsEqual( this.formatter.objectValueForString(string), amount, Units.MEYears, isFloating, relativeError, string);
								if(!plural && !isFloating) {
									string = this.percentString("-10", short, relativeError);
									this.assertDurationIsEqual( this.formatter.objectValueForString(string), -0.1, Units.MEFraction, isFloating, relativeError, string);
									string = this.percentString("0", short, relativeError);
									this.assertDurationIsEqual( this.formatter.objectValueForString(string), 0, Units.MEFraction, isFloating, relativeError, string);
									string = this.percentString("50", short, relativeError);
									this.assertDurationIsEqual( this.formatter.objectValueForString(string), 0.5, Units.MEFraction, isFloating, relativeError, string);
									string = this.percentString("100", short, relativeError);
									this.assertDurationIsEqual( this.formatter.objectValueForString(string), 1.0, Units.MEFraction, isFloating, relativeError, string);
									string = this.percentString("200", short, relativeError);
									this.assertDurationIsEqual( this.formatter.objectValueForString(string), 2.0, Units.MEFraction, isFloating, relativeError, string);
								}
							}
						}
					}				
				}
			}
		})); 

		return testSuites;
	}

};

var guiTest = {

	didFinishHandler: null,
	
	run: function(didFinishHandler) {
		this.requestStop = false;
		this.didFinishHandler = didFinishHandler;
		this.runTest1();
	},
	
	stop: function() {
		this.requestStop = true;
		disableAlert = false;
	},
	
	
	fkeys: {
	  'backspace':8,  'tab':9,  'return':13,  'pause':19,  'escape':27,  
	  'space':32,  'pageup':33, 'pagedown':34, 'end':35, 'home':36, 
	  'left':37, 'up':38, 'right':39, 'down':40, 'printscreen':44, 
	  'insert':45, 'delete':46, 'f1':112, 'f2':113, 'f3':114, 'f4':115, 
	  'f5':116, 'f7':117, 'f8':119, 'f9':120, 'f10':121, 'f11':122, 
	  'f12':123, 'numlock':144, 'scrolllock':145
	},

	pkeys: {
	  "0":48, "1":49, "2":50, "3":51, "4":52, "5":53, "6":54, "7":55, "8":56,
	  "9":57, ";":59, "=":61, "a":65, "b":66, "c":67, "d":68, "e":69, "f":70,
	  "g":71, "h":72, "i":73, "j":74, "k":75, "l":76, "m":77, "n":78, "o":79,
	  "p":80, "q":81, "r":82, "s":83, "t":84, "u":85, "v":86, "w":87, "x":88,
	  "y":89, "z":90, "+":107, "-":109, ".":110, ",":188, ".":190, "/":191,
	  "`":192, "[":219, "\\":220, "]":221, "\"":222
	},

	switchToActivitiesView: function() {
		YAHOO.util.UserAction.mousedown($('activityButton2'), { clientX: 1, clientY: 1 });
		YAHOO.util.UserAction.mouseup($('activityButton2'), { clientX: 1, clientY: 1 });	
	},
	
	switchToResourcesView: function() {
		YAHOO.util.UserAction.mousedown($('resourcesButton2'), { clientX: 1, clientY: 1 });
		YAHOO.util.UserAction.mouseup($('resourcesButton2'), { clientX: 1, clientY: 1 });	
	},
	
	switchToUtilizationView: function() {
		YAHOO.util.UserAction.mousedown($('utilizationButton2'), { clientX: 1, clientY: 1 });
		YAHOO.util.UserAction.mouseup($('utilizationButton2'), { clientX: 1, clientY: 1 });		
	},
	
	
	runTests: function() {
		var testSuite = new YAHOO.tool.TestSuite("GUITest");
		testSuite.add( new YAHOO.tool.TestCase({
			
			name: "Activities",		
			
			setUp: function() {
				guiTest.switchToActivitiesView();
			},

			elementIsVisible: function(elem) {
				if(!elem)
					return true
				if(elem.style && elem.style.display == 'none')
					return false;
				return this.elementIsVisible(elem.parentNode);
			},
			
			activeInputElement: function() {
				var inputElements = document.getElementsByTagName("INPUT");
				for(var i=0; i<inputElements.length; i++){
					var input = inputElements[i];
					if(input.focus && !input.disabled && this.elementIsVisible(input))
						return input;
				}
				return null;
			},

			activityViewSelectLastActivity: function() {
				var objects = activitiesViewController.outlineController.flatObjects;
				var keyDownCount = objects ? objects.length : 0;
				for(var i=0; i<keyDownCount; i++)
					YAHOO.util.UserAction.keydown(document.body, { keyCode: guiTest.fkeys.down });
			},
			
			ignore_testCreateActivities: function() {
				this.activityViewSelectLastActivity();
				YAHOO.util.UserAction.keydown(document.body, { keyCode: guiTest.pkeys['n'], ctrlKey:true });					
				this.wait(function(){
					this.activeInputElement().value = "Vorgang 1";
					YAHOO.util.UserAction.keydown(document.body, { keyCode: guiTest.fkeys["return"] });		
				}, 1);					
			},
			
			ignore_testCreateActivitiesWithoutGUI: function() {
				for(var i=0; i<40; i++) {
					var activity = activitiesViewController.testAddActivity();
					activity.setValueForKey("Vorgang "+i, "title");
					activitiesViewController.refresh();
				}
			},
						
			testChangeActivityNamesRepeatetly: function() {
				var flatObjects = activitiesViewController.outlineController.getFlatObjects();
				if(flatObjects.length) {
					var index = 0;
					var k = 0;
					var me = this;
					var changeActivityName = function(flatObjects, index, k) {
						var object = flatObjects[index];
						var title = "Vorgang "+k;					
						object.setValueForKey(title, "title");
						activitiesViewController.refresh();
						activitiesViewController.moc.synchronize();		//Nach einiger Zeit kommt out of memory im Safari
//						activitiesViewController.moc.save();
						index++;
						if(index >= flatObjects.length)
							index = 0;
						k++;
						if(guiTest.requestStop)							
							guiTest.didFinishHandler();
						else {
							setTimeout(function(){
								changeActivityName(flatObjects, index, k);
							}, 10);
						}
					}
					changeActivityName(flatObjects, index, k);
				}
			}
		})); 

	    var TestRunner = YAHOO.tool.TestRunner; 
		TestRunner.clear();
		TestRunner.add(testSuite);
		TestRunner.run();

	},
	
	runTest1: function() {
		var flatObjects = activitiesViewController.outlineController.getFlatObjects();
		var array = flatObjects;
		if(flatObjects.length) {
			var index = 0;
			var k = Math.random() * 1000;
			var me = this;
			var changeActivityName = function(flatObjects, index, k) {
				$('guiTestButton').style.backgroundColor = k % 2 ? '#fff' : '#f99';
				var object = flatObjects[index];
				var title = "Vorgang "+k;					
				object.setValueForKey(title, "title");
				activitiesViewController.refresh();				
				activitiesViewController.moc.synchronizeAndSave(true);
				index++;
				if(index >= flatObjects.length)
					index = 0;
				k++;
				if(guiTest.requestStop)	{					
					$('guiTestButton').style.backgroundColor = '#eee';
					guiTest.didFinishHandler();
				}
				else {
					setTimeout(function(){
						changeActivityName(flatObjects, index, k);
					}, 10);
				}
			}
			changeActivityName(array, index, k);
		}
	},
	
	
	runTest2: function() {
		disableAlert = true;
		var k = 0;

		// Solange wie nicht guiTest.requestStop:
		//	Wenn kein Lock gesetzt:
		//		Wähle zufällig zwei Aktivitäten aus.
		//		Löse eine eventuelle vorhandene Verbindung zwischen Ihnen auf.
		//		Lege eine neue Verbindung an - der Typ ist ebenfalls zufällig.
		//		Speichere die Änderungen.
		//		Wiederhole nach einer kurzen Pause.
		
		var chainMethods = [activitiesViewController.chainFinishStart, activitiesViewController.chainFinishFinish, activitiesViewController.chainStartFinish, activitiesViewController.chainStartStart];

		var applyRandomChainMethod = function() {
			chainMethods[Math.ceil(Math.random()*3)].call(activitiesViewController);
		}

		var isLocked = function() {
			var result = false;
			var lockImages = $$('.lockImage');
			return lockImages.length && lockImages[0].src && lockImages[0].src.endsWith('ClosedLockSmall.png');
		}

		var testMethod = function() {
			k++;
			$('guiTestButton').style.backgroundColor = k % 2 ? '#fff' : '#f99';
			var flatObjects = activitiesViewController.outlineController.getFlatObjects();
			var length = flatObjects.length;
			if(length>1 && !isLocked()) {
				var num = Math.random()*(length-1);
				var i1 = Math.floor(num);
				var i2 = i1+1;
				var activities = [flatObjects[i1], flatObjects[i2]];
				activitiesViewController.selectActivities(activities);
				activitiesViewController.disconnectActivities();
				applyRandomChainMethod();
				activitiesViewController.moc.save();
//				YAHOO.log("k: "+ k);
			}
		}
			
		var timer = window.setInterval(function(){
			if(guiTest.requestStop){
				$('guiTestButton').style.backgroundColor = '#eee';
				guiTest.didFinishHandler();
				window.clearInterval(timer);
				return;
			}
			if(!isLocked())
				testMethod();			
		}, 500);	

	}
	
	
};
