Peepler = {};

Peepler.Resource = function () {};

//Set defaults
Object.extend(Peepler.Resource, {
	model: function (model, options) {
		options = options || {};
		options.singular = model.underscore();

		options.plural = options.singular.pluralize(options.plural);

		var default_options = {
			prefix: '/api',
			format: 'json',
			urls: {
				'show' : "/" + options.plural + "/:id",
				'list': '/' + options.plural
			}
		};

		options = Object.extend(default_options, options);
		return Jester.Resource.model(model, options);
	}
});

window.Resource = Peepler.Resource;

//Disable form submission even if it's valid
Object.extend(Validation.prototype, {
	onSubmit: function (e) {
		this.validate();
		e.stop();
	}
});

//Add validation rule
Validation.add('validate-email-or-yahoo-id', function (value) {
	var validator = Validation.get('validate-email');
	if (!validator.test(value)) {
		value += '@yahoo.com';
		return validator.test(value);
	}

	return true;
});

//Add abort methods
Ajax.autoID = 1000;

Ajax.activeRequests = $H({});

Ajax.Responders.register({
	onCreate: function (request) {
		var h = Ajax.activeRequests;
		request.ID = Ajax.autoID++;
		h.set(request.ID, request);
		Ajax.activeRequestsCount++;
	},
	onComplete: function (request) {
		var h = Ajax.activeRequests;
		h.unset(request.ID);
		Ajax.activeRequestsCount--;
	}
});

Object.extend(Ajax, {
	abort: function () {
		var h = Ajax.activeRequests;
		h.each(function(o) {
			o.value.abort();
		});
	}
});

Object.extend(Ajax.Request.prototype, {
	abort: function () {
		this.transport.onreadystatechange = Prototype.emptyFunction;
		this.transport.abort();
		Ajax.activeRequestsCount--;
		Ajax.activeRequests.unset(this.ID);
	}
});

Peepler.UI = Class.create({

	/**
	 * Constructor
	 */
	initialize: function (c)
	{
		Object.extend(this, c);
		document.observe('dom:loaded', this.onDomLoaded.bind(this));

	},

	/**
	 * Called when the dom finished loading
	 */
	onDomLoaded: function ()
	{
		Object.extend(this, {
			searchForm: $$(this.searchForm).first(),
			emailLabel: $$(this.emailLabel).first(),
			emailField: $$(this.emailField).first(),
			searchButton: $$(this.searchButton).first(),
			statusEl: $$(this.statusEl).first(),
			profilesContainer: $$(this.profilesContainer).first()
		});

		if (window.location.hash) {
			var f = window.location.hash.split('/');
			if (f[0] == '#results') {
				this.setSearchingState();
				this.onEmailEncrypted(f[1]);
			}
		}

		this.emailField.observe('focus', this.onEmailFieldFocus.bind(this));

		if (!$F(this.emailField)) {
			this.emailLabel.show();
		}

		this.validation = new Validation(this.searchForm, {onFormValidate: this.onFormValidate.bind(this), useTitles: true});

		Event.observe(document.body, 'click', function () {
			this.validation.reset();
		}.bind(this));

	},

	/**
	 * Displays the preloader
	 */
	setSearchingState: function ()
	{
		if (!this.statusEl) {
			this.statusEl = $('main').appendChild(new Element('h2', {'class': 'section-title'}));
		}

		if (!this.profilesContainer) {
			this.profilesContainer = $('main').appendChild(new Element('ul', {'class': 'profiles'}));
		}

		this.count = 0;

		this.statusEl.addClassName(this.preloaderCls).innerHTML = this.lang.loading;

		this.profilesContainer.removeClassName(this.latestProfilesCls).addClassName(this.resultsCls);
		this.profilesContainer.innerHTML = '';
	},

	/**
	 * Called when all the plugins have been loaded
	 */
	onPluginsLoaded: function (plugins)
	{
		this.plugins = plugins;
	},

	/**
	 * Called when the email field receives focus
	 */
	onEmailFieldFocus: function ()
	{
		this.emailLabel.hide();
	},

	/**
	 * Called when the search button is clicked
	 */
	onFormValidate: function (valid)
	{

		if (!valid) { return; }

		//Abort all requests
		Ajax.abort();

		//The value is a valid one so we check if it's a yahoo id
		validator = Validation.get('validate-email');
		if(!validator.test(this.emailField.value)) {
			this.emailField.value += '@yahoo.com';
		}

		this.setSearchingState();
		var email = $F(this.emailField), Email = Resource.model('Email');
		Email.find(email, {view: 'encrypted'}, {
			requestHeaders: {
				'X-Peepler-ApiKey': Peepler.ApiKey
			},
			onComplete: this.onEmailEncrypted.bind(this)
		});
	},

	/**
	 * Called when the email has been encrypted
	 */
	onEmailEncrypted: function(encryptedEmail)
	{
		if (typeof encryptedEmail == 'object') {
			encryptedEmail = encryptedEmail.value;
		}

		//Hijax
		window.location = Peepler.baseUrl + '#results/' + encryptedEmail;

		if (!this.plugins) {
			if (!Peepler.Plugins) {
				var Plugin = Resource.model('Plugin');
				Plugin.find('all', null, {
					requestHeaders: {
						'X-Peepler-ApiKey': Peepler.ApiKey
					},
					onComplete: function (plugins) {
						Peepler.Plugins = plugins;
						this.onEmailEncrypted.call(this, encryptedEmail);
					}.bind(this)
				});
				return;
			}
			this.plugins = Peepler.Plugins;
		}

		var Profile = Resource.model('Profile'), left = 0;

		this.plugins.each(function (plugin) {
			var c, o; left = left || this.plugins.size();

			c = function () {
				left--;
				if (0 === left) {
					var s = this;
					(function () {
						s.onSearchComplete.call(s);
					}).defer();
				}
			};

			o = {
				requestHeaders: {
					'X-Peepler-ApiKey': Peepler.ApiKey
				},
				onSuccess: c.bind(this),
				onException: c.bind(this),
				onComplete: this.onProfileLoaded.bind(this)
			};

			Profile.find('first', {encryptedEmail: encryptedEmail, plugin: plugin.name}, o);
		}, this);
	},	
	/**
	 * Called after each profile is loaded
	 */
	onProfileLoaded: function (profile)
	{
		var s, o;

		this.count++;
		var normalize = function (str) {
			return str.replace('°', '').replace('!', '').replace(' ', '-').toLowerCase();
		};

		o = Object.extend({
			cls: 'profile-' + normalize(profile.locationName)
		}, profile);

		if (profile.uri) {
			s = this.urlProfileTemplate.evaluate(o);
		} else {
			s = this.profileTemplate.evaluate(o);
		}

		this.profilesContainer.insert(s);

	},

	/**
	 * Called when the search is complete
	 */
	onSearchComplete: function ()
	{
		if (this.count) {
			this.statusEl.innerHTML = this.lang.success;
		} else {
			this.statusEl.innerHTML = this.lang.failure;
		}

		this.statusEl.removeClassName(this.preloaderCls);
		this.profilesContainer.insert('<li class="promo"><span class="promo-title">PROMO</span><div class="profile-avatar-container"><a href="http://urbankid.ro"  target="_blank" title="UrbanKid.ro - e fun sa fi parinte"><img src="http://urbankid.ro/b/uk-simplu-125.png" width="125" height="125" alt="UrbanKid.ro - e fun sa fi parinte" border="0" /></a></div></li>');


	}
});

