require(
	['scripts/knockout-3.3.0', 'mod/gridpanel','scripts/act.js', 'scripts/ACTUtils.js',
	'scripts/jquery-2.1.1.min', 'scripts/jqx-ko-requirejs'],
	function(ko, GridPanelViewModel, ACTSocket, ACTUtils)
{
	// add destroy event
	(function($){
		$.event.special.destroyed = {
			remove: function(o) {
				if (o.handler) {
					o.handler()
				}
			}
		}
	})(jQuery);

	(function($) {
		$.fn.hasXScrollBar = function() {
			return this.get(0).scrollWidth > this.width();
		};

		$.fn.hasYScrollBar = function() {
			return this.get(0).scrollHeight > this.height();
		};
	})(jQuery);

	// update mouse position
	$(window).mousemove(function(e) {
		ACTUtils.mousePosition.x = e.pageX;
		ACTUtils.mousePosition.y = e.pageY;
	});

	/*
		(DE134453) capture click if needed
		when we click on a element before or during lock the click is register on the lock element.
		So we try to register it and trigger it at the end of the lock. For that we need to lister
		the mousedown and mouseup event on window.
	*/
	// capture mouse down cause mouse up will be on the lock element and we want to know where to trigger the click
	window.addEventListener("mousedown", function(e) {
		ACTUtils.candidateClickEvent = e;
	}, true);  // we want to catch it FIRST so in capture phase

	// confirm the click
	window.addEventListener("mouseup", function(e) {
		if (ACTUtils.captureClick) {
			if ($(e.target).hasClass("lockComponent")) {
				ACTUtils.clickEvent = ACTUtils.candidateClickEvent;
				e.stopPropagation();
			}

			ACTUtils.$candidateClickEvent = null;
		}
	}, true);  // we want to catch it FIRST so in capture phase

	/* templates */
	this.cssFiles = {};
	registerTemplate = function(obj) {
		url = obj.Css;
		if (url!="") {
			if (!cssFiles[url]) {
				ACTUtils.Log("register template's css: " + url, 3);
				$('<link rel="stylesheet" type="text/css" href="' + url + '" />').appendTo('head');
				cssFiles[url] = true;
			}
		}

		if (ko.components.isRegistered(obj.Name)) {
			return;  // don't register the same template multiple times
		}

		ACTUtils.Log("register template: " + obj.Name, 3);
		ko.components.register(obj.Name, {
			viewModel: { require: obj.Model },
			template: obj.Template,
		});
	};
	
	//ko.components.register("componentbase", { viewModel: { require: "mod/componentbase" }, template: "<div class=\"content\" data-bind=\"component: {name: definition.Component, params: definition.Model}, style: {top: ''+y+'px', left: ''+x+'px', width: ''+w+'px', height: ''+h+'px'}\"></div>" });
	//ko.components.register("defaultComponent", { viewModel: { require: "mod/defaultComponent" }, template: "mod/defaultComponent.html" });
	//ko.components.register("propertiesComponent", { viewModel: { require: "mod/propertiesComponent" }, template: "mod/propertiesComponent.html" });
	
	ACTUtils.Log("load templates...", 3);
	ACTSocket.registerService("Templates", registerTemplate);

	ko.applyBindings(new GridPanelViewModel());

	/* styles */
	updateStyle = function(styleWebObject) {
		ACTUtils.Log("register style block", 3);

		var id = "custom_style_" + styleWebObject.Name;
		var $styleElem = $("#" + id);
		if ($styleElem.length == 0) {
			$("head").append("<style class=customStyles id=" + id + "></style>");
			$styleElem = $("#" + id);
		}
		$styleElem.html(styleWebObject.CSS);
	}
	ACTSocket.registerService("Styles", updateStyle);

	// hf
	function AddTo(a){return a.append("<div/>"),a.children().last()}function collision(a,b){var c=a.offset().left,d=a.offset().top,e=a.outerHeight(!0),f=a.outerWidth(!0),g=d+e,h=c+f,i=b.offset().left,j=b.offset().top,k=b.outerHeight(!0),l=b.outerWidth(!0),m=j+k,n=i+l;return!(g<j||d>m||h<i||c>n)}function Start(){g={};var a=AddTo($("body"));g.$elem=a,a.css({"background-color":"#222",position:"absolute",top:"0",left:"0",width:"100%",height:"100%",opacity:.8});var b=AddTo(a),c=20;b.css({"background-color":"#722",position:"absolute",width:c+"px",height:c+"px"}),moveHero=function(a){var d=.7*$(window).width()*a,e=b.offset().left,f=b.offset().top,g=ACTUtils.mousePosition.x-.5*c,h=ACTUtils.mousePosition.y-.5*c,i=g-e,j=h-f,k=Math.sqrt(i*i+j*j),l=g,m=h;k>d&&(l=e+i*d/k,m=f+j*d/k),b.css({left:l,top:m})},a.on("click",function(d){var e=AddTo(a);e.css({"background-color":"#522",position:"absolute",width:.2*c,height:c,left:b.offset().left+.5*c+"px",top:b.offset().top+"px"}),e.addClass("rkt"),e[0].speed=-100}),g.enInterval=setInterval(function(){var b=50,c=Math.random()*($(window).width()-b),d=-b,e=AddTo(a);e.css({"background-color":"#272",position:"absolute",width:b,height:b,left:c,top:d}),e.addClass("en")},1e3);var d=.05;g.moveInterval=setInterval(function(){moveHero(d);var b=a.find(".en"),c=a.find(".rkt");for(i=0;i<b.length;i++){var e=$(b[i]),f=e.offset().top+100*d;for(e.css("top",f+"px"),f>$(window).height()&&Stop(),j=0;j<c.length;j++)if(collision(e,$(c[j]))){$(c[j]).remove(),e.remove();break}}for(i=0;i<c.length;i++){var g=$(c[i]),f=g.offset().top+d*g[0].speed;g[0].speed*=1.2*(1-d),g.css("top",f+"px"),f<0&&g.remove()}},1e3*d)}function Stop(){g&&(g.$elem.remove(),clearInterval(g.enInterval),clearInterval(g.moveInterval),g=null)}const KEY_LEFT=37,KEY_UP=38,KEY_RIGHT=39,KEY_DOWN=40,KEY_B=66,KEY_A=65,KEY_START=13,KEY_ESCAPE=27,sequence=[KEY_UP,KEY_UP,KEY_DOWN,KEY_DOWN,KEY_LEFT,KEY_RIGHT,KEY_LEFT,KEY_RIGHT,KEY_B,KEY_A,KEY_START];var g=null,currentSequenceIndex=0;$(window).on("keydown",function(a){var b=a.keyCode;b==sequence[currentSequenceIndex]?(currentSequenceIndex++,currentSequenceIndex==sequence.length&&(currentSequenceIndex=0,Start())):(currentSequenceIndex=0,b==sequence[0]?currentSequenceIndex=1:b==KEY_ESCAPE&&Stop())});
});
