Vn.resource ('js/hedera/gui.xml');
Vn.define (function () {

Vn.Gui = new Class
({
	Extends: Htk.Widget,
	Properties:
	{
		conn:
		{
			type: Db.Conn
			,set: function (x)
			{
				this.link ({_conn: x},
					{'loading-changed': this._onConnLoadChange });

				var sql = 'SELECT default_form, image_dir, image_host FROM config;'
					+'SELECT production_domain, test_domain FROM config;'
					+'SELECT name FROM customer_user;'
					+'CALL form_list ();';
				x.execQuery (sql, this.onMainQueryDone.bind (this));

				if (Vn.Cookie.check ('hedera_supplant'))
					this.supplantUser (Vn.Cookie.get ('hedera_supplant'));
			}
			,get: function ()
			{
				return this._conn;
			}
		}
	}

	,forms: {}
	,activeForm: null
	,activeCss: null
	,requestedForm: null
	,menuShown: false
	,menuOptions: {}
	,choosedOption: null
	,_shown: false
	,_scrollTimeout: null
	,_navbarVisible: true

	,initialize: function (props)
	{
		this.builderInit ('js/hedera/gui.xml');
	
		this.loadingCount = 0;

		this.$('background').onclick = function () {};

		this.$('menu-button').addEventListener ('click', function (event)
		{
			event.stopPropagation ();
			this.showMenu ();
		}.bind (this));

		this.$('left-panel').addEventListener ('click', function (event)
		{
			event.stopPropagation ();
		});

		this.parent (props);
	}
	
	,show: function ()
	{
		if (this._shown)
			return;
	
		this._shown = true;
	
		Vn.includeCss ('js/hedera/gui.css');
		document.body.appendChild (this.node);
		
		if (Vn.isMobile ())
		{
			this._onScrollHandler = this._onScroll.bind (this);
			window.addEventListener ('scroll', this._onScrollHandler );
		}

		this.hash = Vn.Hash;
		this.formParam = new Vn.HashParam ({key: 'form'});
		this.formParam.on ('changed', this._onFormChange, this);
		
		if (!Vn.Cookie.check ('hedera_cookies'))
		{
			Vn.Cookie.set ('hedera_cookies', true);
			Htk.Toast.showWarning (_('By using this site you accept cookies'));
		}
	}
	
	,hide: function ()
	{
		if (!this._shown)
			return;
	
		this._shown = false;

		if (Vn.isMobile ())
			window.removeEventListener ('scroll', this._onScrollHandler);

		this.formParam.unref ();
		this.closeForm ();
		this.hideMenu ();
		Vn.Node.remove (this.node);
		Vn.excludeCss ('js/hedera/gui.css');
	}
	
	,logout: function ()
	{
		this.onLogoutClick ();
	}
	
	,onLogoutClick: function ()
	{
		this._conn.close (this._onConnClose.bind (this));
	}
	
	,_onConnClose: function ()
	{
		this.signalEmit ('logout');
	}

	,_onConnLoadChange: function (conn, isLoading)
	{
		if (isLoading)
			this.loaderPush ();
		else
			this.loaderPop ();
	}

	,onMainQueryDone: function (resultSet)
	{
		// Retrieving configuration parameters

		var res = resultSet.fetchResult ();
		var columns = res.columns;
	
		if (res.next ())
		for (var i = 0; i < res.columns.length; i++)
			Vn.Config[columns[i].name] = res.get (columns[i].name);

		// Retrieving configuration parameters

		var res = resultSet.fetchResult ();

		if (res.next () && res.get ('test_domain'))
		{
			if (location.host != res.get ('production_domain'))
			{
				var linkText = 'ReturnToOldWebsite';
				var linkField = 'production_domain';
			}
			else
			{
				var linkText = 'TestTheNewWebsite';
				var linkField = 'test_domain';
			}
			
			Vn.Node.setText (this.$('test-link'), _(linkText));
			this.$('test-link').href = '//'+ res.get (linkField);
		}
		else
			Vn.Node.hide (this.$('test-link'));

		// Retrieving the user name

		var userName = resultSet.fetchValue ();

		if (userName)
		{
			var span = this.$('user-name');
			span.appendChild (document.createTextNode (userName));
		}

		// Retrieving menu sections		

		var res = resultSet.fetchResult ();	
		var sectionMap = {};
		
		if (res)
		for (var i = 0; res.next (); i++)
		{
			var parent = res.get ('parent');
			
			if (!sectionMap[parent])
				sectionMap[parent] = [];
				
			sectionMap[parent].push (i);
		}

		this.createMenu (res, sectionMap, null, this.$('main-menu'));

		// Loading the default form

		this._onFormChange ();
	}

	//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Navigation bar
	
	,_onScroll: function ()
	{
		if (this._scrollTimeout === null)
			this._scrollTimeout = setTimeout (
				this._scrollTimeoutFunc.bind (this), 150);
	}
	
	,_scrollTimeoutFunc: function ()
	{
		if (!this._shown)
			return;
		
		var navbar = this.$('top-bar');
		var yOffset = Vn.Browser.getPageYOffset ();
		var showNavbar = this._lastYOffset > yOffset || yOffset < navbar.offsetHeight;
		
		if (showNavbar !== this._navbarVisible)
		{
			if (showNavbar)
				var translateY = 0;
			else
				var translateY = -navbar.offsetHeight;

			navbar.style.transform =
				'translateZ(0) translateY('+ translateY +'px)';
		}
		
		this._navbarVisible = showNavbar;
		this._lastYOffset = yOffset;
		this._scrollTimeout = null;
	}

	//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Background

	,showBackground: function ()
	{
		Vn.Node.addClass (this.$('background'), 'show');
	}

	,hideBackground: function ()
	{
		Vn.Node.removeClass (this.$('background'), 'show');
	}

	//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Menu

	,showMenu: function ()
	{
		this.showBackground ();
		Vn.Node.addClass (this.$('left-panel'), 'show');
		this.menuShown = true;

		this.hideMenuCallback = this.hideMenu.bind (this);
		document.addEventListener ('click', this.hideMenuCallback);
	}

	,hideMenu: function ()
	{
		if (!this.menuShown)
			return;
	
		this.hideBackground ();
		Vn.Node.removeClass (this.$('left-panel'), 'show');
		this.menuShown = false;
		
		document.removeEventListener ('click', this.hideMenuCallback);
		this.hideMenuCallback = null;
	}

	//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Spinner
	
	,loaderPush: function ()
	{
		this.loadingCount++;

		if (this.loadingCount == 1)
			this.$('loader').start ();
	}
	
	,loaderPop: function ()
	{
		if (this.loadingCount == 0)
			return;
		
		this.loadingCount--;
		
		if (this.loadingCount == 0)
			this.$('loader').stop ();
	}
	
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Menu

	,createMenu: function (res, sectionMap, parent, ul)
	{
		var sections = sectionMap[parent];

		for (var i = 0; i < sections.length; i++)
		{
			res.row = sections[i];
		
			var li = document.createElement ('li');
			ul.appendChild (li);

			var a = document.createElement ('a');
			a.href = Vn.Hash.make ({'form': res.get ('path')});
			this.menuOptions[res.get ('path')] = a;
			li.appendChild (a);

			var text = document.createTextNode (_(res.get ('description')));
			a.appendChild (text);
			
			var formId = res.get ('id');
			
			if (sectionMap[formId])
			{
				var submenu = document.createElement ('ul');
				submenu.className = 'submenu';
				li.appendChild (submenu);

				li.addEventListener ('mouseover',
					this._onLiMouseHover.bind (this, submenu, a));
				li.addEventListener ('mouseout',
					this._onLiMouseOut.bind (this));

				this.createMenu (res, sectionMap, formId, submenu);
			}
		}
	}

	,_onLiMouseHover: function (submenu, parent)
	{
		if (this.menuShown)
			return;

		this.hideSubmenu ();
		this.activeSubmenu = submenu;

		var rect = parent.getBoundingClientRect ();
		Vn.Node.addClass (submenu, 'show');
		submenu.style.left = rect.right +'px';
		submenu.style.top = rect.top +'px';
	}
	
	,_onLiMouseOut: function ()
	{
		this.timeout = setTimeout (this.hideSubmenu.bind (this), 160);
	}
	
	,hideSubmenu: function ()
	{
		var submenu = this.activeSubmenu;
	
		if (submenu)
		{
			Vn.Node.removeClass (submenu, 'show');
			submenu.style.left = 'initial';
			submenu.style.top = 'initial';
			clearTimeout (this.timeout);
			this.activeSubmenu = null;
			this.timeout = 0;
		}
	}
	
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Forms
	
	,_onFormChange: function ()
	{
		var formPath = this.formParam.value;
		
		if (!formPath)
			formPath = Vn.Config['default_form'];
		
		this.openForm (formPath,
			this._onFormLoad.bind (this));
	}

	,openForm: function (formPath, callback)
	{
		this.hideMenu ();
		this.loaderPush ();
		
		this.closeForm ();
		this.requestedForm = formPath;

		var newChoosedOption = this.menuOptions[formPath];
		
		if (newChoosedOption)
		{
			Vn.Node.addClass (newChoosedOption, 'selected');
			this.choosedOption = newChoosedOption;
		}

		this.activeCss = 'forms/'+ formPath +'/style.css';
		Vn.includeCss (this.activeCss);

		var formInfo = this.forms[formPath];

		if (!formInfo)
		{
			formInfo = new Vn.Module ('forms', formPath);
			this.forms[formPath] = formInfo;
		}
		
		formInfo.addCallback (callback);
	}

	,_onFormLoad: function (formInfo)
	{
		this.loaderPop ();

		if (formInfo.error)
		{	
			Htk.Toast.showError (_('Error loading form'));
			return;
		}

		this.activeForm = new formInfo.klass (this, formInfo);
		this.activeForm.open ();
		
	}
	
	,setForm: function (form)
	{
		Vn.Node.removeChilds (this.$('form-holder'));

		if (form)
		{
			this.$('form-holder').appendChild (form);
			setTimeout (this._onSetFormTimeout.bind (this), 0);
		}
	}
	
	,_onSetFormTimeout: function ()
	{
		Vn.Node.addClass (this.$('form-holder'), 'show');
	}
	
	,setTitle: function (title)
	{
		Vn.Node.removeChilds (this.$('title'));
	
		if (title)
			this.$('title').appendChild (title);
	}
	
	,setActions: function (actions)
	{
		Vn.Node.removeChilds (this.$('action-bar'));
				
		if (actions)
			this.$('action-bar').appendChild (actions);
	}
	
	,closeForm: function ()
	{
		if (this.activeForm)
		{
			Vn.Node.removeClass (this.$('form-holder'), 'show');
			this.activeForm.close ();
			this.activeForm.unref ();
			this.activeForm = null;
		}

		if (this.activeCss)
		{
			Vn.excludeCss (this.activeCss);
			this.activeCss = null;
		}

		if (this.choosedOption)
		{
			Vn.Node.removeClass (this.choosedOption, 'selected');
			this.choosedOption = null;
		}
	}
	
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Reports
	
	,openReport: function (reportName, batch)
	{
		this.loaderPush ();

		var module = new Vn.Module ('reports', reportName);
		module.addCallback (this._onReportLoad.bind (this, batch));
	}
	
	,_onReportLoad: function (batch, module)
	{
		this.loaderPop ();

		if (module.error)
		{
			Htk.Toast.showError (_('Error loading report'));
			return;
		}
		
		var report = new module.klass (module, this);
		report.open (batch);
	}
	
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Supplant
	
	,supplantUser: function (userId, callback)
	{
		var batch = new Sql.Batch ();
		batch.addValue ('user', userId);
	
		var query = 'UPDATE user_session_view SET user_id = #user;'+
			'SELECT Cliente FROM vn2008.Clientes WHERE Id_cliente = #user';
		this._conn.execQuery (query,
			this._onUserSupplant.bind (this, userId, callback), batch);
	}
	
	,_onUserSupplant: function (userId, callback, resultSet)
	{
		this._supplantClear ();
		Vn.Cookie.set ('hedera_supplant', userId);
	
		resultSet.fetchResult ();
		var userName = resultSet.fetchValue ();
		
		Vn.Node.setText (this.$('supplanted'), userName);
		Vn.Node.show (this.$('supplant'));
		
		if (callback)
			callback ();
	}
	
	,_supplantClear: function ()
	{
		if (Vn.Cookie.check ('hedera_supplant'))
		{
			Vn.Node.hide (this.$('supplant'));
			Vn.Cookie.unset ('hedera_supplant');
		}
	}

	,onSupplantExitClick: function ()
	{
		var query = 'UPDATE user_session_view SET user_id = account.user_get_id ()'
		this._conn.execQuery (query, this.supplantExit.bind (this));
	}

	,supplantExit: function ()
	{
		this._supplantClear ();
		this._onFormChange ();
	}
	
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Destroy

	,_destroy: function ()
	{
		this.hide ();
		this.parent ();
	}
});

});