/**
 * Finder style navigation
 * 
 */

LBi.Finder = (function() {

	/**
	* Finder
	*
	*/
	var Finder = function(node, settings) {
		this.settings = $.extend({}, Finder.Defaults, settings);
		var settings = this.settings;
		this.root = node;
		this.clip = $(settings.clipSelector, node);
		this.view = this.clip.parent();
		this.crumb = $(settings.crumbSelector, node);
		this.resizer = $(settings.resizeSelector, node);
		
		this.initEvents();
		this.breadcrumb();

		var visible = /active/.test(this.root.className);
		if(visible) {
			this.reflow();
		}
	};

	Finder.prototype = {
		constructor: Finder,

		initEvents:function () {
			// delegated click handler inside finder view
			this.clip.bind('click', this.handleClick.bind(this));
			
			// specific toggle click
			var toggle = $('a.finder_show_hide', this.root);
			toggle.click(this.handleToggle.bind(this));
		},

		handleClick: function(e) {
			var link = $(e.target).closest('a');
			if (link.length) {
				var prevent = false;
				var cls = link.attr('class');

				if(/edit/.test(cls)) {
					prevent = this.edit(link);
				} else if(/add_folder/.test(cls)) {
					prevent = this.addToFolder(link);
				} else if(/name/.test(cls)) {
					prevent = this.load(link);
				} else if(/save/.test(cls)) {
					prevent = this.save(link);
				} else if(/up|down|remove/.test(cls)){
					prevent = this.modifyFolder(link, 'self');
				} else if(/left/.test(cls)) {
					prevent = this.modifyFolder(link, 'parent');
				}

				if(prevent) {
					e.preventDefault();
				}
			}
		},

		toggle:function(open) {
			var root = $(this.root);
			if(open) {
				root.addClass('active');
			} else {
				root.toggleClass('active');
			}
		},

		handleToggle:function(e) {
			e.preventDefault();
			this.toggle();
		},

		activate: function(link) {
			var settings = this.settings;
			var item = link.closest(settings.itemSelector);
			var sibs = item.siblings();
			item.addClass(settings.activeClass);

			sibs.removeClass(settings.activeClass);
			sibs.removeClass(settings.editableClass);

			var col = this.settings.columnSelector
			var list = link.closest(col);
			list.nextAll(col).remove();

			this.breadcrumb();

			return item;
		},

		load: function(link) {
			var item = this.activate(link);
			if (item.hasClass(this.settings.folderClass)) {
				$.get(
					this.noCache(link.attr('href')),
					this.displayFolder.bind(this),
					'xml'
				);
			} else {
    			this.reflow();
	    		$.get(
					this.noCache(link.attr('href')),
					function(){},
					'xml'
				);
			}
			return true;
		},

		edit: function(link) {
			this.activate(link);
			this.reflow();
			
			var self = this;
			$.get(
				this.noCache(link.attr('href')),
				function(response, status) {
					self.editItem(response, status, link);
				},
				'xml'
			);

			return true;
		},

		modifyFolder:function(link, mode) {
			var settings = this.settings;
			var url = link.attr('href');
			var col = settings.columnSelector;
			
			var folder = link.closest(col);
			if(mode == 'parent') {
				folder = folder.prev(col);
			}
			
			this.loadToFolder(folder, url);
			return true;
		},

		loadToFolder:function(folder, href) {
			var self = this;
			$.get(
				this.noCache(href),
				function(response) {
					self.replaceFolder(folder, $('html', response).text());
				},
				'xml'
			);
		},

		addToFolder:function(link) {
			var settings = this.settings;
			var href = link.attr('href');
			var cls = link.attr('class');
			var col = settings.columnSelector;
			var folder = link.closest(col);
			var list = folder.find('ul');
			var self = this;

			$.get(
				this.noCache(href),
				function(response){
					var html = $('html', response).text();
					var item = $(html);
					list.prepend(item);
					var siblings = item.siblings();
					siblings.removeClass(settings.activeClass);
					siblings.removeClass(settings.editableClass);
				},
				'xml'
			);

			return true;
		},

		replaceFolder:function(folder, html) {
			var settings = this.settings;
			var col = settings.columnSelector;

			folder.nextAll(col).remove();
			folder.replaceWith($(html));
			
			this.reflow();
			this.breadcrumb();
		},

		displayFolder: function(response) {
			var settings = this.settings;
			var folder = $('folder', response)[0];
			var html = $('html', folder).text();

			
			this.clip.append($(html));
			this.reflow();
		},

		displayRoot:function(e) {
			e.preventDefault();
			var self = this;
			var link = $(e.target).closest('a');
			$.get(
				this.noCache(link.attr('href')),
				function(response) {
					self.clip.empty();
					self.displayFolder(response);
					self.breadcrumb();
				},
				'xml'
			);
		},

		editItem: function(response, status, link) {
			var settings = this.settings;
			var item = link.closest(settings.itemSelector);
			var folder = $('folder', response)[0];
			var html = $($('html', folder).text());

			var edit = $('div.editable', item);
			if (edit.length) {
				edit.replaceWith(html);
			} else {
				item.append(html);
			}

			item.addClass(settings.editableClass);
		},

		reflow: function() {
			this.toggle(true);
			var settings = this.settings;
			var lists = this.clip.find(settings.columnSelector);
			var width = 0;
			var height = '100%';
			for (var i = 0; i < lists.length; i++) {
				width += lists[i].offsetWidth;
			}

			var viewer = this.view[0];
			var avail = viewer.offsetWidth;
			var scroll = 0;
			if (width > avail) {
			//	height = viewer.offsetHeight - 18;
				scroll = Math.min(avail - width, 0);
			}

			lists.eq(0).addClass('first');

			this.view.css({ width: avail });

			this.clip.animate({
				width: width,
				height: height
			});

			if (settings.autoScroll) {
				this.scrollTo(scroll);
			}
		},

		save: function(link) {
			var settings = this.settings;
			var edit = link.closest('.'+settings.editableClass);
			var item = link.closest(settings.itemSelector);

			var input = edit.find('input:text')[0];
			if(input) {
				var value = encodeURIComponent(input.value);
				var param = input.name + '=' + value + '&';
				var href = link.attr('href');
				var folder = link.closest(settings.columnSelector);
				href = href.replace(/(\?|\&)/, '$1' + param);				

				this.loadToFolder(folder, href);
			}

			return true;
		},

		breadcrumb: function() {
			var settings = this.settings;
			var crumb = this.crumb;
			var item = settings.itemSelector;
			var path = this.clip.find(item + '.' + settings.activeClass + ' ' + settings.labelSelector);
			
			crumb.find(item).remove();

			path.each(function() {
				var node = this;
				var item = $('<li></li>');
				var link = $(node).clone();
				item.append(link);
				crumb.append(item);
				link.bind('click', function(e) {
					e.preventDefault();
					$(node).trigger('click');
				});
			});
		},

		scrollTo: function(x) {
			this.clip.parent().animate({
				scrollLeft: Math.abs(x)
			});
		},

		noCache:function(url) {
			var delim = /\?/.test(url)? '&' : '?';
			var rand = delim + "_rndm=" + (new Date()).getTime();

			return url.replace(/($|(#[^\$]+))/, rand + '$1');
		}
	};

	/**
	* Defaults
	* 
	*/
	Finder.Defaults = {
		clipSelector: 'div.clip',
		crumbSelector: 'div.breadcrumb',
		columnSelector: 'ul',
		itemSelector: 'li',
		labelSelector: 'a.name',
		resizeSelector: '.resizer',
		folderClass: 'folder',
		activeClass: 'active',
		editableClass: 'editable',
		autoScroll: true
	};


	Finder.instances = $.registerPlugin('finder', Finder);

	/**
	* Expose
	* 
	*/
	return Finder;

})(jQuery);
