var Application = new Class({
	Implements: [Events, Class.Occlude, Log, Chain],
	property: 'Application',
	
	// Constants
	GOOGLE_USER_ACCOUNT: 'UA-26084706-1',
	SITE_NAME: 'Mezz',

	// Variables
	productionMode: false,
	url: null,
	jsonRequest: null,
	config: null,
	page: {
		name: null,
		element: null,
		instance: null
	},
	userData: null,
	facebookUserData: null,
	analyticsManager: null,


	// Class instances


	/*
	 * Initialize
	 */
	initialize: function()
	{
		this.element = $(document.body);
		if ( this.occlude() ) return this.occluded;
		
		this.enableLog();
//		this.disableLog();
		//this.log("Application::initialize()");
		
		// Set variables
		this.page.name = this.element.get('id');
		this.page.element = this.element;
		this.url = new URI();

		// Config
		this.config = {};
		this.config.requestPath = {};
		this.config.facebook = {};

		var analyticsOptions = {
			onLoadTrackPageView: true,/* track page view or not on initial load*/
			pageViewStr: '/mezz',/*you should start your page name with a leading slash '/'*/
			//shouldLog: false,/* console logging for firebug*/
			//duplicateAsPageView: false,
			domainName: this.url.get('host')
		};


		switch( this.url.get('host') )
		{
			case 'mezz.dev' :

				this.config.requestPath = {
					login : 'json/login.php',
					newsletter : 'json/newsletter.php',
					comment : 'json/comment.php',
					search : {
							result: '../json/search.php',
							more: '/search.html'
						},
					news : {
						item : 'json/news.php'
					},
					programme : {
						attend : 'json/attend.php',
						inviteFriend : 'json/tell_a_friend.php',
						comment : 'json/comment.php'
					},
					afterglow : {
						rate : 'json/rate.php',
						tellAFriend : 'json/tell_a_friend.php',
						photo : {
							upload: '../../json/upload_photo.php',
							add: '../../json/add_photos.php'
						},
						setlist : {
							addVideo: 'json/add_video.php',
							addSong: 'json/add_song.php',
							editSong: 'json/edit_song.php',
							changeSongOrder: 'json/change_song_order.php'
						},
						comment : 'json/comment.php'
					}
				}

				// Analytics
				analyticsOptions.shouldLog = true;

				// Facebook app id
				this.config.facebook.appId = '222226321156043';

			break;
			
			case 'www128.ws21.tijdelijke-url.nl' :
			case 'www.mezz.nl' :
			default :
			
				this.productionMode = true;

				// Facebook app id
				this.config.facebook.appId = '159388907469645';

				if(this.url.get('host') == 'tijdelijke-url.nl')
				{
					document.domain = 'tijdelijke-url.nl';
				}
				else if(this.url.get('host') == 'www.mezz.nl')
				{
					document.domain = 'mezz.nl';
				}
				
				if(this.url.get('directory') == '/dev/')
				{
					this.config.requestPath = {
						login : '../json/login.aspx',
						newsletter : '../json/newsletter.aspx',
						search : {
							result: '../json/search.aspx',
							more: 'search.aspx'
						},
						news : {
							item : '../json/news.aspx'
						},
						programme : {
							attend : '../json/attend.aspx',
							inviteFriend : '../json/tell_a_friend.aspx',
							comment : '../json/comment.aspx'
						},
						afterglow : {
							rate : '../json/rate.aspx',
							tellAFriend : '../json/tell_a_friend.aspx',
							photo : {
								upload: '../../json/upload_photo.ashx',
								add: '../../json/add_photos.aspx'
							},
							setlist : {
								addVideo: '../json/add_video.aspx',
								addSong: '../json/add_song.aspx',
								editSong: '../json/edit_song.aspx',
								changeSongOrder: '../json/change_song_order.aspx'
							},
							comment : '../json/comment.aspx'
						}
					}
				}
				else
				{
					this.config.requestPath = {
						login : '/json/login.aspx',
						newsletter : '/json/newsletter.aspx',
						search : {
							result: '/json/search.aspx',
							more: '/search.aspx'
						},
						news : {
							item : '/json/news.aspx'
						},
						programme : {
							attend : '/json/attend.aspx',
							inviteFriend : '/json/tell_a_friend.aspx',
							comment : '/json/comment.aspx'
						},
						afterglow : {
							rate : '/json/rate.aspx',
							tellAFriend : '/json/tell_a_friend.aspx',
							photo : {
								upload: '/json/upload_photo.ashx',
								add: '/json/add_photos.aspx'
							},
							setlist : {
								addVideo: '/json/add_video.aspx',
								addSong: '/json/add_song.aspx',
								editSong: '/json/edit_song.aspx',
								changeSongOrder: '/json/change_song_order.aspx'
							},
							comment : '/json/comment.aspx'
						}
					}
				}

			break;

		}
		
		this.log("this.url.get('host'): "+ this.url.get('host'));
		this.log("this.config.facebook.appId: " + this.config.facebook.appId);
		
		// Analytics manager
		this.analyticsManager = new AnalyticsManager(this.GOOGLE_USER_ACCOUNT, this.SITE_NAME, analyticsOptions);

		// Page
		this.initPage( this.page.name );
	},

	initPage: function( name )
	{
		this.log("Application::initPage(" + name + ")");

		var options = {};

		switch( name )
		{
			case 'home':
				this.page.instance = new Home( name, this.element, options );
			break;

			case 'programme':
				this.page.instance = new Programme( name, this.element , options );
			break;

			case 'programme-detail':
				this.page.instance = new ProgrammeDetail( name, this.element , options );
			break;

			case 'afterglow':
				this.page.instance = new Afterglow( name, this.element , options );
			break;

			case 'afterglow-detail':
				options = { background: '/image/background_color.jpg' };

				this.page.instance = new AfterglowDetail( name, this.element , options );
			break;

			case 'news':
				this.page.instance = new News( name, this.element , options );
			break;

			case 'contact':
				this.page.instance = new Contact( name, this.element, options );
			break;

			case 'order-tickets':
				this.page.instance = new OrderTickets( name, this.element, options );
			break;

			case 'order-tickets-login':
				this.page.instance = new AccountLogin( name, this.element, options );
			break;

			case 'order-tickets-success':
				this.page.instance = new OrderTicketsSuccess( name, this.element, options );
			break;

			case 'newsletter-sign-out':
				this.page.instance = new NewsletterSignOut( name, this.element, options );
			break;

			case 'account-create':
				this.page.instance = new Account( name, this.element, options );
			break;

			case 'account-create-email':
				this.page.instance = new AccountCreateEmail( name, this.element, options );
			break;

			case 'account-edit':
				this.page.instance = new Account( name, this.element, {type: 'edit'} );
			break;

			case 'account-forgotten-password':
				this.page.instance = new AccountForgottenPassword( name, this.element, options );
			break;

			case 'account-change-password':
				this.page.instance = new AccountChangePassword( name, this.element, options );
			break;

			case 'search':
				this.page.instance = new Search( name, this.element, options );
			break;

			default:
				this.page.instance = new Page( name, this.element, options );
			break;
		}
	},
	
	/*
	 * Request
	 */
	request: function(requestData)
	{
		this.log("Application::request(" + requestData + ")");

		var method = (requestData.method) ? requestData.method : 'post';
		var link = (requestData.link) ? requestData.link : 'ignore';

		if(this.jsonRequest && link == 'cancel')
		{
			this.jsonRequest.cancel();
		}

		var onRequest = (requestData.onRequest) ? requestData.onRequest : this.onRequest.bind(this);
		var onSuccess = (requestData.onSuccess) ? requestData.onSuccess : this.onSuccess.bind(this);
		var onFailure = (requestData.onFailure) ? requestData.onFailure : this.onFailure.bind(this);
		var onException = (requestData.onException) ? requestData.onException : this.onException.bind(this);

		this.jsonRequest = new Request.JSON({
			method: method,
			url: requestData.url,
			link: link,
			onRequest: onRequest,
			onSuccess: onSuccess,
			onFailure: onFailure,
			onException: onException
		});

		// Send request
		//this.log("requestData.params: " + requestData.params);

		if(this.productionMode)
		{
			//this.log('this.jsonRequest.send(' + Object.toQueryString(requestData.params) + ')');
			this.jsonRequest.send( Object.toQueryString(requestData.params) );
		}
		else
		{
			//this.log('this.jsonRequest.send("JSONData="' + JSON.encode(requestData.params).toString() + ')');
			this.jsonRequest.send("JSONData=" + JSON.encode(requestData.params));
		}
	},

	getRequest: function()
	{
		this.log("getRequest()");
		
		return this.request;
	},

	/*
	 * Retrieve results handlers
	 */
	onRequest: function()
	{
		this.log("Application::onRequest()");

	},

	onSuccess: function(responseText, responseXML)
	{
		this.log("Application::onSuccess(" + responseText + ", " + responseXML + ")");

	},

	onFailure: function(xhr)
	{
		this.log("Application::onFailure(" + xhr + ")");

	},

	onError: function(text, error)
	{
		this.log("Application::onError(" + text + ", " + error + ")");

	},

	onException: function(headerName, value)
	{
		this.log("Application::onException(" + headerName + ", " + value + ")");

	},

	/*
	 * Get user data
	 */
	getUserData: function()
	{
		this.log("Application::getUserData()");

		return this.userData;
	},

	/*
	 * Set user data
	 */
	setUserData: function(data)
	{
		this.log("Application::setUserData(" + data + ")");

		this.userData = data;
	},

	/*
	 * Get Facebook user id
	 */
	getFacebookUserId: function()
	{
		this.log("Application::getFacebookUserId()");

		return this.facebookUserId;
	},

	/*
	 * Set Facebook user id
	 */
	setFacebookUserId: function(id)
	{
		this.log("Application::setFacebookUserId(" + id + ")");

		this.facebookUserId = id;
	},

	/*
	 * Get config
	 */
	getConfig: function()
	{
		this.log("Application::getConfig()");

		return this.config;
	},

	/*
	 * Track page
	 */
	trackPage: function(name)
	{
		this.log("Application::trackPage(" + name + ")");

		this.analyticsManager.trackPage(name);
	},

	/*
	 * Track event
	 */
	trackEvent: function(category, action, opt_label, opt_value)
	{
		this.log("Application::trackEvent(" + category + ", " + action + ", " + opt_label + ", " + opt_value + ")");

		if(category) category = category.toLowerCase();
		if(action) action = action.toLowerCase();
		if(opt_label) opt_label = opt_label.toLowerCase();
		if(opt_value) opt_value = opt_value.toLowerCase();

		this.analyticsManager.trackEvent(category, action, opt_label, opt_value);
	},

	initFacebook: function()
	{
		this.log("Application::initFacebook()");
		
		FB.init({
			appId: this.config.facebook.appId,
			cookie: true,
			status: true,
			xfbml: true,
			oauth: true
		});
	},

	checkFacebookLoginStatus: function(handlers, perms)
	{
		this.log("Application::checkFacebookLoginStatus(" + handlers + ", " + perms + ")");

		FB.getLoginStatus(function(response) {
			this.log("FB.getLoginStatus(" + response + ")");

			for(var i in response)
			{
				this.log("response[" + i + "]: " + response[i]);
			}

			for(var j in response.authResponse)
			{
				this.log("response.authResponse[" + j + "]: " + response.authResponse[j]);
			}

			if(response.authResponse)
			{
				// logged in and connected user, someone you know
				this.log("user logged in");

				// Save users Facebook id
				if(response.authResponse.userID) this.setFacebookUserId(response.authResponse.userID);

				// Continue
				if(handlers.onSuccess.handler)
				{
					handlers.onSuccess.handler.attempt(handlers.onSuccess.arguments, this);
				}
			}
			else
			{
				// no user session available, someone you dont know
				this.log("user NOT logged in");

				this.showFacebookLogin(handlers, perms);
			}
		}.bind(this));

	},

	showFacebookLogin: function(handlers, perms)
	{
		this.log("Application::showFacebookLogin()");

		FB.login(function(response) {
			if(response.authResponse)
			{
				for(var j in response.authResponse)
				{
					this.log("response.authResponse[" + j + "]: " + response.authResponse[j]);
				}
				
				// Save users Facebook id
				if(response.authResponse.userID) this.setFacebookUserId(response.authResponse.userID);

				if(handlers.onSuccess.handler)
				{
					handlers.onSuccess.handler.attempt(handlers.onSuccess.arguments, this);
				}
			}
			else
			{
				this.log('User cancelled login or did not fully authorize.');
				if(handlers.onFailure.handler)
				{
					handlers.onFailure.handler.attempt(handlers.onFailure.arguments, this);
				}
			}
		}.bind(this),
		{
			scope: perms
		});

	}
	
});

window.addEvent("domready", function() {

	var application = new Application();
	
//	console.log("CONFIG: " + window.config);
	
	if(window.config)
	{
//		console.log("CONFIG: " + window.config.userData);
		if(window.config.userData)
		{
			application.setUserData(window.config.userData);
		}
	}

});
