/*jslint laxbreak:true */
/*jslint laxcomma:true */
/*jslint loopfunc:true */
/*jslint strict:true */
/*jslint browser:true */
/*jslint devel:true */

define([
	"underscore"
	, "jquery"
	, "backbone"
	, "bootstrap"
	, "async"

	, "config"

	, "collections/server"

	, "text!../../templates/sidebar/layout.html"
	, "text!../../templates/sidebar/server-list-item.html"
	, "text!../../templates/sidebar/modal-new-server.html"

	// Plugins
	, "jquery-ui"
]
, function (
_
, $
, Backbone
, Bootstrap
, async

, Config

, ServerCollection

, tmplSideBarLayout
, tmplServerListItem
, tmplModalNewServer
) {
	"use strict";

	var SideBar		= Backbone.View.extend({
		events:				{
			"click > ul > li:last-child > span > a.sidebar-list-action":	"_addServerItem"
		}

		, router:				null

		, initialize:			function (options) {
			_.bindAll(this
				, "renderServerItem"
				, "changeServerItemState"
				, "_addServerItem"
				, "_routerActionPlaylist"
				, "_routerActionClient"
				, "_addPlaylistItem"
			);

			var that		= this
			, serverModel	= null
			;

			SideBar.__super__.initialize.apply(that, arguments);

			this.servers	= options.servers;

			that.$el.html(tmplSideBarLayout);

			async.forEach(this.servers, that.renderServerItem, function __fnSideBarViewCbInitialRender() {
				that.trigger("rendered");

				that.router	= new Backbone.Router.extend({
					"playlist":					that._routerActionPlaylist
					, "servers/:server":		that._routerActionClient
					, ":server/items/:item":	that._routerActionClient
					//"*actions": "defaultRoute" // matches http://example.com/#anything-here
				});
			});

			this.servers.on("add", function (server) {
				that.renderServerItem(server);
			});

			this.$el.delegate("> ul > li:first-child", "click", function __fnSideBarEventDblclickPlaylist(event) {
				Backbone.Router.prototype.navigate("playlist", true);

				setTimeout(function __fnSideBarViewTimeoutTogglePlaylistClass() {
					that.$el.find("li.selected").removeClass("selected");
					$(event.target).parents("ul:first").find("> li:first-child").addClass("selected");
				}, 10);
			});

			this.$el.find("> ul > li:first > span").droppable({
				activeClass:	"droppable"
				, hoverClass:	"droppable-hover"
				, scope:		"list-item"
				, tolerance:	"touch" // We really need this cause our items
										// are much bigger than the droppable
				, drop:			that._addPlaylistItem
			});
		}

		, select:					function (serverModel) {
			var that	= this
			,	cid		= (serverModel.cid && "#" + serverModel.cid) || serverModel
			,	$server	= that.$el.find(cid)
			;

			that.$el.find("li.selected").removeClass("selected");
			$server.addClass("selected");
		}

		, _routerActionPlaylist:	function (event) {
console.log(event);
		}

		, _routerActionClient:		function (event) {
console.log(event);
		}

		, _addServerItem:			function(event) {
			var that	= this
			, modalEl	= $(tmplModalNewServer)
			;

			modalEl.modal();

			modalEl.find("button[data-save='modal']").on("click", function (event) {
				modalEl.find("form").submit();
			});

			modalEl.find("form").on("submit", function (event) {
				var $input	= $(event.target).find("input")
				, value		= $input.val()
				, protocol	= "http"
				, port		= 3689
				, domain	= ""
				, errors	= []
				;

				if (value.substr(-1) === "/") {
					value		= value.substr(0, value.length - 1);
				}

				if (/^(?:http|daap)(?:s)?:\/\//.test(value)) {
					protocol	= value.substring(0, value.indexOf(":")).replace("daap", "http");

					value		= value.substr(value.indexOf(":") + 3);
				}

				if (value.indexOf(":") > 0) {
					port		= value.substring(value.indexOf(":") + 1);

					value		= value.substring(0, value.indexOf(":"));
				} else if (protocol === "https") {
					port		= 443;
				}

				domain	= value.toLowerCase();

				if (isNaN((port = parseInt(port, 10)))) {
					errors.push("Invalid port number: 3689");
				}

				if (protocol !== "http" && protocol !== "https") {
					errors.push("Invalid protocol: http(s)");
				}

				if (_.isEmpty(domain)
					|| /^([a-z0-9]([\-a-z0-9]*[a-z0-9])?\\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/.test(domain)) {
					errors.push("Invalid server domain");
				}

				if (errors.length > 0) {
					alert("Please correct the following errors:\n" + errors.join("\n"));
				} else {
					modalEl.modal("hide");

					that.servers.add({
						protocol:	protocol
						, port:		port
						, hostname:	domain
					});
				}

				return false;
			});

			modalEl.on("hidden", function (event) {
				$(event.target).remove();
			});
		}

		, _addPlaylistItem:	function (event, ui) {
			var that		= this
			,	dropData	= $(ui.draggable[0]).data()
			,	item		= _.clone(dropData)
			;

			if (item.draggable) {
				delete item.draggable;
				delete item.uiDraggable;
			}

			that.trigger("add:playlist-item", item);
		}

		, renderServerItem:	function (item) {
			var that	= this
			, itemHtml	= _.template(tmplServerListItem, {
							cid:			item.cid
							, server_name:	item.getName()
						})
			, $item	= $(itemHtml)
			;

			this.$el.find("ul:first > li > ul.siderbar-server-list").append($item);

			item.on("change", function __fnSideBarViewClientItemChanged(event) {
				if (event.get("name")) {
					$item.find("span > span").text(event.getName());
				}
			});

			item.client.on("state", function __fnSideBarViewEventClientState(client, state) {
				that.changeServerItemState($item.find("span > i:first-child"), client, state);
			});

			$item.find("a.sidebar-list-action").on("click", function (model) {
				return function __fnSideBarClickRemoveAction (event) {
					var confirmMessage	= "Are you sure you want to delete:\n" + item.getName();

					if (window.confirm(confirmMessage)) {
						$(event.target).parents("li:first").fadeOut(300, function() { $(this).remove(); });

						setTimeout(function () {
							model.destroy();
						}, 10);
					}

					event.preventDefault();
					return false;
				};
			}(item));

			$item.on("click", function __fnSideBarViewEventDblClickItem(event) {
				// FIXME: This needs to check the state of the client and debounce
				that.$el.find("li.selected").removeClass("selected");
				$item.addClass("selected");
/*
				if (item.client.state < item.client._states.loaded) {
					item.client.fetchDatabases(item.client.fetchDatabase);
				} else {
					console.log(item.client.collections);
				}
*/
				Backbone.Router.prototype.navigate("servers/" + item.id, true);
			});
		}

		, changeServerItemState:	function ($glyph, client, state) {
				var newClass	= "icon-folder-closed"
				;

				switch (state) {
					case 2:
					case 5:
						newClass	= "icon-loading";
					break;
					case 3:
						newClass	= "icon-exclamation-sign";
					break;
					case 4:
						newClass	= "icon-ok-sign";
					break;
					case 6:
						newClass	= "icon-folder-open";
					break;
					case -1:
						newClass	= "icon-warning-sign";
					break;
					default:
					case 0:
					case 1:
						newClass	= "icon-folder-closed";
					break;
				}

				$glyph.removeClass();
				$glyph.addClass(newClass);
		}
	});

	return SideBar;
});