/*jslint laxbreak:true */
/*jslint laxcomma:true */
/*jslint loopfunc:true */
/*jslint strict:true */
/*jslint browser:true */
/*jslint devel:true */
/**
 * TODO: If the user agrees, set the username/passs in a cookie
**/
define([
	"underscore"
	, "backbone"
	, "toolbox"
	, "models/dmap-type"
	, "models/dmap"
], function (_, Backbone, Toolbox, DMAPType, DMAPModel) {
	"use strict";

	var that

	// TODO: Could be interesting to set a userage, could possibly affect transcoding on the server side
	, xhr				= function (url, responseType, callback) {
		var xhr = new XMLHttpRequest();
		var contentType = "text/plain; charset=utf-8";

		if (typeof responseType === "function") {
			callback		= responseType;
			responseType	= "arraybuffer";
		}

		xhr.open("GET", url, true);
		xhr.responseType	= responseType;
		xhr.setRequestHeader("Content-type", contentType);

		// TODO: Add this:
		// xhr.timeout = 4000;
		// xhr.ontimeout = function () { alert("Timed out!!!"); }

		console.log(that.attributes.password, that.attributes.username, window.btoa((that.attributes.username || "") + ":" + (that.attributes.password || "")));

		if (!_.isEmpty(that.attributes.password) || !_.isEmpty(that.attributes.username)) {
			var basicAuth	= window.btoa((that.attributes.username || "") + ":" + (that.attributes.password || ""));

			xhr.withCredentials = true;
			xhr.setRequestHeader("Authorization", "Basic " + basicAuth);
		}

		//xhr.overrideMimeType('text/plain; charset=x-user-defined');
		try {
			xhr.onerror = function() {console.log(arguments, this);};
			xhr.onabort = function() {console.log(arguments, this);};
			xhr.onload = function(e) {
				if (this.status === 200) {
					callback(null, this.response);
				} else if (this.status === 401) {
					that.trigger("unauthorized", [this, e]);
				} else {
					callback(e.status);
				}
			};

			xhr.send();
		} catch (e) {
			console.error(e);
			callback(e, null);
		}
	}

	, fetchContentTypes	= function (success, error) {
		xhr(that.url("/content-codes?"), function (err, content) {
			if (err) {
				error || (error = function (err) {throw [err, content]}());

				error(err, content);

			} else {
				that.collections.contentCodes	= new DMAPModel([], {
					buffer:	content
				});
				success && success(content);
			}
		});
	}

	, fetchServerInfo	= function (success, error) {
		xhr(that.url("/server-info?"), function (err, content) {
			if (err) {
				error || error = function (err) {throw [err, content]}();

				error(err, content);

			} else {
				that.collections.serverInfo	= new DMAPModel([], {
					buffer:			content
					, contentCodes:	that.collections.contentCodes
				});
				success && success(content);
			}
		});
	}

	, fetchLogin		= function () {

	}

	, fetchDatabases	= function () {

	}

	, fetchDatabase		= function () {

	}

	, fetchPlaylists	= function () {

	}

	, Client			= Toolbox.Base.extend({

		constructor:	function(attributes, options) {
			that	= this;

			_.extend(that, Client.defaults);
			_.extend(that.attributes, attributes);

			return this;
		}

		, init:		function () {
			fetchContentTypes(function () {
				fetchServerInfo(function () {
					that.trigger("inited", that.collections);
				});
			});

			return this;
		}

		,logout:	function () {

		}

		,url:		function (request) {
			var uri	= ""
			;

			if (typeof request === "string") {
				uri	= request; // Add leading slash here!
			}

			return this.attributes.protocol + "://" + this.attributes.hostname + ":" + this.attributes.port + uri;
		}
	}, {
		defaults: {
			attributes:		{
				protocol:		window.location.protocol.replace(":", "")
				, hostname:		window.location.hostname
				, port:			3689
				, path:		""
				, username:	""
				, password:	""
			}

			, collections:	{
				contentCodes:	null

				, serverInfo:	null

				, session:	{
					id:			null
				}

				, databasesInfo:null

				, databases:	null

				, playlistsInfo:null

				, genres:		null

				, artists:		null

				, albums:		null
			}
		}

		, lawl: function() {
			console.info(arguments);
		}
	});

	_.extend(Client.prototype, Backbone.Events, {});

	return Client;
});