dojo.provide("tests.webmap.widget.CalloutBox");

dojo.require("doh.runner");
dojo.require("webmap.widget.CalloutBox");
dojo.require("tests.Util");

var div;
var pointToNode;
function doCalloutBoxSetup(){
	tests.Util.resetDom();
	div = document.createElement("div");
	document.body.appendChild(div);
	pointToNode = document.createElement("div");
	document.body.appendChild(pointToNode);
	div.id = "cb";
	pointToNode.id = "ptn";
}
doh.register("tests.webmap.widget.CalloutBox", 
	[
		{
			name: "postCreate_no_xy",
			widget: null,
			posCount: 0,
			pointerCount: 0,
			nodeCount: 0,
			setUp: function(){
				doCalloutBoxSetup();
				var _this = this;
				this.widget = new webmap.widget.CalloutBox({
					_addPointer: function(){
						_this.pointerCount++;
						this._pointer = {
							destroy: function(){}
						}
					},
					position: function(){_this.posCount++;},
					_setNodeBox: function(){_this.nodeCount++;}
				}, div); 
			},
			runTest: function(){
				tests.assertEqual(0, this.posCount);
				tests.assertEqual(1, this.pointerCount);
				tests.assertEqual(1, this.nodeCount);
				this.widget._setNodeBox = null;
				this.widget.postCreate();
				tests.assertEqual(0, this.posCount);
				tests.assertEqual(2, this.pointerCount);
				tests.assertEqual(1, this.nodeCount);
			},
			tearDown: function(){
				this.widget.destroy();
			}
		},
		{
			name: "postCreate_with_xy",
			widget: null,
			posCount: 0,
			pointerCount: 0,
			nodeCount: 0,
			setUp: function(){
				doCalloutBoxSetup();
				var _this = this;
				this.widget = new webmap.widget.CalloutBox({
					x:1, y:2,
					_addPointer: function(){
						_this.pointerCount++;
						this._pointer = {
							destroy: function(){}
						}
					},
					position: function(){_this.posCount++;},
					_setNodeBox: function(){_this.nodeCount++;}
				}, div); 
			},
			runTest: function(){
				tests.assertEqual(1, this.posCount);
				tests.assertEqual(1, this.pointerCount);
				tests.assertEqual(1, this.nodeCount);
				this.widget._setNodeBox = null;
				this.widget.postCreate();
				tests.assertEqual(2, this.posCount);
				tests.assertEqual(2, this.pointerCount);
				tests.assertEqual(1, this.nodeCount);
			},
			tearDown: function(){
				this.widget.destroy();
			}
		},
		{
			name: "destroy",
			widget: null,
			setUp: function(){
				doCalloutBoxSetup();
				this.widget = new webmap.widget.CalloutBox({pointToNode:pointToNode}, div);
			},
			runTest: function(){
				tests.assertEqual(1, dojo.query(".webmapPointer").length);
				this.widget.destroy();
				tests.assertEqual(null, dojo.byId("cb"));
				tests.assertEqual(0, dojo.query(".webmapPointer").length);
			}
		},
		{
			name: "position_xy_left_top",
			widget: null,
			getViewport: dijit.getViewport,
			getViewportCount: 0,
			resizeCount: 0,
			resize: null,
			setUp: function(){
				doCalloutBoxSetup();
				this.widget = new webmap.widget.CalloutBox({pointToNode:pointToNode}, div);
				var _this = this;
				this.widget.resize = function(r){_this.resizeCount++; _this.resize = r;};
				dijit.getViewport = function(){_this.getViewportCount++; return {l:0,t:0,w:800,h:600};};
			},
			runTest: function(){
				this.widget.position(200, 100);
				tests.assertEqual(1, this.getViewportCount);
				tests.assertEqual(1, this.resizeCount);
				tests.assertEqual({"l": 240, "t": 98}, this.resize);
			},
			tearDown: function(){
				this.widget.destroy();
				dijit.getViewport = this.getViewport;
			}
		},
		{
			name: "position_xy_right_top",
			widget: null,
			getViewport: dijit.getViewport,
			getViewportCount: 0,
			resizeCount: 0,
			resize: null,
			setUp: function(){
				doCalloutBoxSetup();
				this.widget = new webmap.widget.CalloutBox({pointToNode:pointToNode}, div);
				var _this = this;
				this.widget.resize = function(r){_this.resizeCount++; _this.resize = r;};
				dijit.getViewport = function(){_this.getViewportCount++; return {l:0,t:0,w:800,h:600};};
			},
			runTest: function(){
				this.widget.position(500, 100);
				tests.assertEqual(1, this.getViewportCount);
				tests.assertEqual(1, this.resizeCount);
				tests.assertEqual({"l": 208, "t": 98}, this.resize);
			},
			tearDown: function(){
				this.widget.destroy();
				dijit.getViewport = this.getViewport;
			}
		},
		{
			name: "position_xy_right_bottom",
			widget: null,
			getViewport: dijit.getViewport,
			getViewportCount: 0,
			resizeCount: 0,
			resize: null,
			setUp: function(){
				doCalloutBoxSetup();
				this.widget = new webmap.widget.CalloutBox({pointToNode:pointToNode}, div);
				var _this = this;
				this.widget.resize = function(r){_this.resizeCount++; _this.resize = r;};
				dijit.getViewport = function(){_this.getViewportCount++; return {l:0,t:0,w:800,h:600};};
			},
			runTest: function(){
				this.widget.position(500, 400);
				tests.assertEqual(1, this.getViewportCount);
				tests.assertEqual(1, this.resizeCount);
				tests.assertEqual({"l": 208, "t": 252}, this.resize);
			},
			tearDown: function(){
				this.widget.destroy();
				dijit.getViewport = this.getViewport;
			}
		},
		{
			name: "position_xy_left_bottom",
			widget: null,
			getViewport: dijit.getViewport,
			getViewportCount: 0,
			resizeCount: 0,
			resize: null,
			setUp: function(){
				doCalloutBoxSetup();
				this.widget = new webmap.widget.CalloutBox({pointToNode:pointToNode}, div);
				var _this = this;
				this.widget.resize = function(r){_this.resizeCount++; _this.resize = r;};
				dijit.getViewport = function(){_this.getViewportCount++; return {l:0,t:0,w:800,h:600};};
			},
			runTest: function(){
				this.widget.position(200, 400);
				tests.assertEqual(1, this.getViewportCount);
				tests.assertEqual(1, this.resizeCount);
				tests.assertEqual({"l": 240, "t": 252}, this.resize);
			},
			tearDown: function(){
				this.widget.destroy();
				dijit.getViewport = this.getViewport;
			}
		},
		{
			name: "position_no_xy",
			widget: null,
			setUp: function(){
				doCalloutBoxSetup();
				this.widget = new webmap.widget.CalloutBox({pointToNode:pointToNode, x:100, y:200}, div);
			},
			runTest: function(){
				tests.assertEqual(100, this.widget.x);
				tests.assertEqual(200, this.widget.y);
				this.widget.position();
				tests.assertEqual(100, this.widget.x);
				tests.assertEqual(200, this.widget.y);
			},
			tearDown: function(){
				this.widget.destroy();
			}
		},
		{
			name: "resize",
			widget: null,
			applyTo: null,
			applyTos: 0,
			args: null,
			shows: 0,
			superclassResize: webmap.widget.CalloutBox.superclass.resize.apply,
			setUp: function(){
				doCalloutBoxSetup();
				var _this = this;
				this.widget = new webmap.widget.CalloutBox({
					_addPointer: function(){
						this._pointer = {
							show: function(){_this.shows++;},
							destroy: function(){}
						}
					},
					pointToNode:pointToNode
				}, div);
				webmap.widget.CalloutBox.superclass.resize.apply = function(a0, a1){
					_this.applyTos++; 
					_this.applyTo = a0;
					_this.args = a1;
				};
			},
			runTest: function(){
				this.widget.resize("resize arg1");
				tests.assertEqual(this.widget, this.applyTo);
				tests.assertEqual(["resize arg1"], this.args);
				tests.assertEqual(1, this.shows);
				tests.assertEqual(1, this.applyTos);
				this.widget.minimized = true;
				this.widget.resize("resize arg2");
				tests.assertEqual(this.widget, this.applyTo);
				tests.assertEqual(["resize arg1"], this.args);
				tests.assertEqual(1, this.shows);
				tests.assertEqual(1, this.applyTos);
				this.widget.minimized = false;
				dojo.style(this.widget.domNode, "display", "none");
				this.widget.resize("resize arg3");
				tests.assertEqual(this.widget, this.applyTo);
				tests.assertEqual(["resize arg1"], this.args);
				tests.assertEqual(1, this.shows);
				tests.assertEqual(1, this.applyTos);
			},
			tearDown: function(){
				webmap.widget.CalloutBox.superclass.resize.apply = this.superclassResize;
				this.widget.destroy();
			}
		},
		{
			name: "show",
			widget: null,
			applyTos: 0,
			applyTo: null,
			args: null,
			superclassShow: webmap.widget.CalloutBox.superclass.show.apply,
			setUp: function(){
				doCalloutBoxSetup();
				this.widget = new webmap.widget.CalloutBox({
					x:100, y:200, pointToNode:pointToNode}, div);
				var _this = this;
				webmap.widget.CalloutBox.superclass.show.apply = function(a0, a1){
					_this.applyTos++; 
					_this.applyTo = a0;
					_this.args = a1;
				};
			},
			runTest: function(){
				this.widget.show();
				tests.assertEqual(this.widget, this.applyTo);
				tests.assertEqual(1, this.applyTos);
				tests.assertEqual([
					{properties:{
							left:{start:this.widget.x}, 
							top:{start:this.widget.y}
						}
					}], this.args);
			},
			tearDown: function(){
				webmap.widget.CalloutBox.superclass.show.apply = this.superclassShow;
				this.widget.destroy();
			}
		},
		{
			name: "hide_not_minimized",
			widget: null,
			applyTos: 0,
			applyTo: null,
			args: null,
			superclassHide: webmap.widget.CalloutBox.superclass.hide.apply,
			setUp: function(){
				doCalloutBoxSetup();
				this.widget = new webmap.widget.CalloutBox({
					pointToNode:pointToNode}, div);
				var _this = this;
				webmap.widget.CalloutBox.superclass.hide.apply = function(a0, a1){
					_this.applyTos++; 
					_this.applyTo = a0;
					_this.args = a1;
				};
			},
			runTest: function(){
				this.widget.hide();
				tests.assertEqual(this.widget, this.applyTo);
				tests.assertEqual([{properties:{
					left:{end:this.widget._pointer.point.x}, 
					top:{end:this.widget._pointer.point.y}}}], 
					this.args);
				tests.assertEqual(1, this.applyTos);
			},
			tearDown: function(){
				webmap.widget.CalloutBox.superclass.hide.apply = this.superclassHide;
				this.widget.destroy();
			}
		},
		{
			name: "hide_minimized",
			widget: null,
			applyTos: 0,
			calls: 0,
			arg: null,
			apply: webmap.widget.CalloutBox.superclass.hide.apply,
			call: webmap.widget.CalloutBox.superclass.hide.call,
			setUp: function(){
				doCalloutBoxSetup();
				this.widget = new webmap.widget.CalloutBox({
					minimized: true,
					pointToNode:pointToNode}, div);
				var _this = this;
				webmap.widget.CalloutBox.superclass.hide.apply = function(a0, a1){
					_this.applyTos++; 
				};
				webmap.widget.CalloutBox.superclass.hide.call = function(a){
					_this.calls++; 
					_this.arg = a; 
				};
			},
			runTest: function(){
				this.widget.hide();
				tests.assertEqual(this.widget, this.arg);
				tests.assertEqual(1, this.calls);
				tests.assertEqual(0, this.applyTos);
			},
			tearDown: function(){
				webmap.widget.CalloutBox.superclass.hide.apply = this.apply;
				webmap.widget.CalloutBox.superclass.hide.call = this.call;
				this.widget.destroy();
			}
		},
		{
			name: "_doMove",
			widget: null,
			applyTos: 0,
			applyTo: null,
			args: null,
			shows: 0,
			apply: webmap.widget.CalloutBox.superclass._doMove.apply,
			setUp: function(){
				doCalloutBoxSetup();
				var _this = this;
				this.widget = new webmap.widget.CalloutBox({
					_addPointer: function(){
						this._pointer = {
							show: function(){_this.shows++;},
							destroy: function(){}
						}
					},
					pointToNode:pointToNode}, div);
				webmap.widget.CalloutBox.superclass._doMove.apply = function(a0, a1){
					_this.applyTos++; 
					_this.applyTo = a0; 
					_this.args = a1; 
				};
			},
			runTest: function(){
				this.widget._doMove("event1");
				tests.assertEqual(this.widget, this.applyTo);
				tests.assertEqual(["event1"], this.args);
				tests.assertEqual(1, this.shows);
				tests.assertEqual(1, this.applyTos);
				this.widget.minimized = true;
				this.widget._doMove("event2");
				tests.assertEqual(this.widget, this.applyTo);
				tests.assertEqual(["event1"], this.args);
				tests.assertEqual(1, this.shows);
				tests.assertEqual(1, this.applyTos);
				this.widget.minimized = false;
				dojo.style(this.widget.domNode, "display", "none");
				this.widget._doMove("event3");
				tests.assertEqual(this.widget, this.applyTo);
				tests.assertEqual(["event1"], this.args);
				tests.assertEqual(1, this.shows);
				tests.assertEqual(1, this.applyTos);
			},
			tearDown: function(){
				webmap.widget.CalloutBox.superclass._doMove.apply = this.apply;
				this.widget.destroy();
			}
		},
		{
			name: "_addPointer_no_pointFromNode",
			widget: null,
			setUp: function(){
				doCalloutBoxSetup();
				var _this = this;
				this.widget = new webmap.widget.CalloutBox({
					x: 100, y:200,
					pointToNode:pointToNode}, div);
			},
			runTest: function(){
				tests.assertTrue(this.widget._pointer._started);
				tests.assertEqual(this.widget, this.widget._pointer.parent);
				tests.assertEqual(this.widget.x, this.widget._pointer.x);
				tests.assertEqual(this.widget.y, this.widget._pointer.y);
				tests.assertEqual(this.widget.pointToNode, this.widget._pointer.pointToNode);
				tests.assertEqual(this.widget.domNode, this.widget._pointer.pointFromNode);
				tests.assertEqual(this.widget.id + "_ptr", this.widget._pointer.id);
			},
			tearDown: function(){
				this.widget.destroy();
			}
		},
		{
			name: "_addPointer_has_pointFromNode",
			widget: null,
			setUp: function(){
				doCalloutBoxSetup();
				var _this = this;
				this.widget = new webmap.widget.CalloutBox({
					x: 100, y:200,
					pointFromNode:pointToNode}, div);
			},
			runTest: function(){
				tests.assertTrue(this.widget._pointer._started);
				tests.assertEqual(this.widget, this.widget._pointer.parent);
				tests.assertEqual(this.widget.x, this.widget._pointer.x);
				tests.assertEqual(this.widget.y, this.widget._pointer.y);
				tests.assertEqual(this.widget.pointFromNode, this.widget._pointer.pointFromNode);
				tests.assertEqual(null, this.widget._pointer.pointToNode);
				tests.assertEqual(this.widget.id + "_ptr", this.widget._pointer.id);
			},
			tearDown: function(){
				this.widget.destroy();
			}
		},
		{
			name: "onAfterMininmize",
			widget: null,
			hide: 0,
			arg: null,
			calls: 0,
			call: webmap.widget.CalloutBox.superclass.onAfterMininmize.call,
			setUp: function(){
				doCalloutBoxSetup();
				var _this = this;
				this.widget = new webmap.widget.CalloutBox({
					x: 100, y:200,
					_addPointer: function(){
						this._pointer = {
							hide: function(){_this.hide++;},
							destroy: function(){}
						}
					}
				}, div);
				webmap.widget.CalloutBox.superclass.onAfterMininmize.call = function(arg){
					_this.calls++;
					_this.arg = arg;
				};
			},
			runTest: function(){
				this.widget.onAfterMininmize();
				tests.assertEqual(1, this.hide);
				tests.assertEqual(1, this.calls);
				tests.assertEqual(this.widget, this.arg);
			},
			tearDown: function(){
				webmap.widget.CalloutBox.superclass.onAfterMininmize.call = this.call;
				this.widget.destroy();
			}
		},
		{
			name: "onAfterShow",
			widget: null,
			show: 0,
			arg: null,
			calls: 0,
			call: webmap.widget.CalloutBox.superclass.onAfterShow.call,
			setUp: function(){
				doCalloutBoxSetup();
				var _this = this;
				this.widget = new webmap.widget.CalloutBox({
					x: 100, y:200,
					_addPointer: function(){
						this._pointer = {
							show: function(){_this.show++;},
							destroy: function(){}
						}
					}
				}, div);
				webmap.widget.CalloutBox.superclass.onAfterShow.call = function(arg){
					_this.calls++;
					_this.arg = arg;
				};
			},
			runTest: function(){
				this.widget.onAfterShow();
				tests.assertEqual(1, this.show);
				tests.assertEqual(1, this.calls);
				tests.assertEqual(this.widget, this.arg);
			},
			tearDown: function(){
				webmap.widget.CalloutBox.superclass.onAfterShow.call = this.call;
				this.widget.destroy();
			}
		},
		{
			name: "onBeforeHide",
			widget: null,
			hide: 0,
			arg: null,
			calls: 0,
			call: webmap.widget.CalloutBox.superclass.onBeforeHide.call,
			setUp: function(){
				doCalloutBoxSetup();
				var _this = this;
				this.widget = new webmap.widget.CalloutBox({
					x: 100, y:200,
					_addPointer: function(){
						this._pointer = {
							hide: function(){_this.hide++;},
							destroy: function(){}
						}
					}
				}, div);
				webmap.widget.CalloutBox.superclass.onBeforeHide.call = function(arg){
					_this.calls++;
					_this.arg = arg;
				};
			},
			runTest: function(){
				this.widget.onBeforeHide();
				tests.assertEqual(1, this.hide);
				tests.assertEqual(1, this.calls);
				tests.assertEqual(this.widget, this.arg);
			},
			tearDown: function(){
				webmap.widget.CalloutBox.superclass.onBeforeHide.call = this.call;
				this.widget.destroy();
			}
		},
		{
			name: "onAfterHide",
			widget: null,
			hide: 0,
			arg: null,
			calls: 0,
			call: webmap.widget.CalloutBox.superclass.onAfterHide.call,
			setUp: function(){
				doCalloutBoxSetup();
				var _this = this;
				this.widget = new webmap.widget.CalloutBox({
					x: 100, y:200,
					_addPointer: function(){
						this._pointer = {
							hide: function(){_this.hide++;},
							destroy: function(){}
						}
					}
				}, div);
				webmap.widget.CalloutBox.superclass.onAfterHide.call = function(arg){
					_this.calls++;
					_this.arg = arg;
				};
			},
			runTest: function(){
				this.widget.onAfterHide();
				tests.assertEqual(1, this.hide);
				tests.assertEqual(1, this.calls);
				tests.assertEqual(this.widget, this.arg);
			},
			tearDown: function(){
				webmap.widget.CalloutBox.superclass.onAfterHide.call = this.call;
				this.widget.destroy();
			}
		},
		{
			name: "onBeforeRestore",
			widget: null,
			show: 0,
			arg: null,
			calls: 0,
			call: webmap.widget.CalloutBox.superclass.onBeforeRestore.call,
			setUp: function(){
				doCalloutBoxSetup();
				var _this = this;
				this.widget = new webmap.widget.CalloutBox({
					x: 100, y:200,
					_addPointer: function(){
						this._pointer = {
							show: function(){_this.show++;},
							destroy: function(){}
						}
					}
				}, div);
				webmap.widget.CalloutBox.superclass.onBeforeRestore.call = function(arg){
					_this.calls++;
					_this.arg = arg;
				};
			},
			runTest: function(){
				this.widget.onBeforeRestore();
				tests.assertEqual(1, this.show);
				tests.assertEqual(1, this.calls);
				tests.assertEqual(this.widget, this.arg);
			},
			tearDown: function(){
				webmap.widget.CalloutBox.superclass.onBeforeRestore.call = this.call;
				this.widget.destroy();
			}
		},
		{
			name: "onAfterRestore",
			widget: null,
			show: 0,
			arg: null,
			calls: 0,
			call: webmap.widget.CalloutBox.superclass.onAfterRestore.call,
			setUp: function(){
				doCalloutBoxSetup();
				var _this = this;
				this.widget = new webmap.widget.CalloutBox({
					x: 100, y:200,
					_addPointer: function(){
						this._pointer = {
							show: function(){_this.show++;},
							destroy: function(){}
						}
					}
				}, div);
				webmap.widget.CalloutBox.superclass.onAfterRestore.call = function(arg){
					_this.calls++;
					_this.arg = arg;
				};
			},
			runTest: function(){
				this.widget.onAfterRestore();
				tests.assertEqual(1, this.show);
				tests.assertEqual(1, this.calls);
				tests.assertEqual(this.widget, this.arg);
			},
			tearDown: function(){
				webmap.widget.CalloutBox.superclass.onAfterRestore.call = this.call;
				this.widget.destroy();
			}
		}
	]
);