var Neighborrow;
if (!Neighborrow) Neighborrow = {};
if (!Neighborrow.Controls) Neighborrow.Controls = {};
if (!Neighborrow.Utils) Neighborrow.Utils = {};

Neighborrow.Utils.setOptions = function(destination, source) {
  for (var property in source) {
    destination[property] = source[property];
  }
  return destination;
}

Neighborrow.Utils.getLeft = function(element) {
	var o = Position.cumulativeOffset(element);
	return o[0];
}

Neighborrow.Utils.getTop = function(element) {
	var o = Position.cumulativeOffset(element);
	return o[1];
}

Neighborrow.Utils.setTop = function(element, value) {
	element.style.top = value + "px";
}

Neighborrow.Utils.setLeft = function(element, value) {
	element.style.left = value + "px";
}

Neighborrow.Utils.getWidth = function(element) {
	return element.getWidth();
}

Neighborrow.Utils.getHeight = function(element) {
	return element.getHeight();
}

Neighborrow.Utils.getElementsByRel = function(root, tag, relVal) {
	var els = root.getElementsByTagName(tag);
	var rels = new Array();
	for (i=0; i<els.length; i++) {
		if (els[i].getAttribute("rel") != null && els[i].getAttribute("rel") == relVal) {
			rels.push(els[i]);
		}
	}
	return rels;
}
/******** Neighborrow.Controls.Pager **********/
Neighborrow.Controls.Pager = Class.create();
Neighborrow.Controls.Pager.prototype = {
	initialize: function() {
		this.holderIds = new Array();
		this.cIndex = 0;
		this.totalPage = 0;
		this.currentPage = 1;
		this.pageDisplayed = 10;		
		this.init = false;
		this.viewManager = null;
	},
	setViewManager: function(viewManager) {
		this.viewManager = viewManager;
	},
	setInit: function(val) {
		this.init = val;
	},
	addHolder: function(holderId)
	{
		this.holderIds.push(holderId);
	},
	resetPager: function(totalPage, currentPage, forceRender) {
		if (this.totalPage != totalPage || !this.init)
		{
			this.totalPage = totalPage;		
			this.currentPage = currentPage;
			this.cIndex = 1;
			this.renderPager();
			this.init = true;
		}
		else {
			if (forceRender) this.renderPager();			
		}
	},
	moveBack: function() {
		if (this.cIndex > 1) this.cIndex -= 1;		
		this.renderPager();
	},
	moveForward: function() {		
		if (this.cIndex < this.totalPage - this.pageDisplayed) this.cIndex += 1;	
		this.renderPager();
	},
	changePage: function(i) {
		this.currentPage = i;
		this.renderPager();
		if (this.viewManager != null) {
			this.viewManager.getInstance().reloadView();
		} else {
			Neighborrow.Controls.ViewManager.getInstance().reloadView();
		}
	},
	setCurrentPage: function(val) {
		this.currentPage = val;
	},
	getCurrentPage: function() {
		return this.currentPage;
	},
	renderPager: function() {						
		var content = "<table id=\"pager_container\" width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr>"; //clear
		if (this.totalPage != 1) {
			content += "<td width=\"10%\"><img src=\"chrome-images/pageBar_separator.png\"/></td>";
			if (this.totalPage > this.pageDisplayed) {				
				content += "<td align=\"right\" class=\"pager_arrow\"><a href=\"javascript:void(0);\" onclick=\"pager.moveBack();\"><img src=\"chrome-images/pager_toleft.gif\" border=\"0\" /></a></td>";			
		        content += "<td class=\"pager_separation\"></td>";
			}
			for (i=this.cIndex; i<this.cIndex + this.pageDisplayed; i++)
			{
				if (i > this.totalPage)
				{
					//content += '<span>&nbsp;&nbsp;&nbsp;</span> | ';
					break;
				}
				else
				{
					if (i != this.currentPage)
					{
						content += "<td class=\"pager_numbers\" align=\"center\"><a href=\"javascript:void(0);\" onclick=\"pager.changePage(" + i + ");\"> " + i + " </a></td>";
                        content += "<td class=\"pager_separation\"></td>";
					}
					else
					{
						content += "<td class=\"pager_numbers_sel\" align=\"center\"> " + i + " </td>";
						content += "<td class=\"pager_separation\"></td>";
					}
				}
			}
			if (this.totalPage > this.pageDisplayed) content += "<td align=\"left\" class=\"pager_arrow\"><a href=\"javascript:void(0);\" onclick=\"pager.moveForward();\"><img src=\"chrome-images/pager_toright.gif\"  border=\"0\"/></a></td>";
		}
		content += "</tr></table>";
		
		if (this.totalPage == 0) {
			content = "";
		}

		for(i=0; i<this.holderIds.length; i++)
		{
			if ($(this.holderIds[i]))
			{
				$(this.holderIds[i]).innerHTML = content;
			}
		}
	}
}

/**************** Neighborrow.Controls.ViewManager ******************/
Neighborrow.Controls.ViewManager = {};
Neighborrow.Controls.ViewManager.Instance = Class.create();
Neighborrow.Controls.ViewManager.Instance.prototype = {
	initialize: function(options)
	{		
		this.loader = null;	
		this.transport = null;
		this.currentView = "list";
		this.setOptions(options);
		this.sortedBy = "";
		this.sortedOrder = "";
	},
	setOptions: function(options) 
	{
		this.options = Neighborrow.Utils.setOptions({
			viewHolderId: '',	
			gridViewUrl: '',
			listViewUrl: '',
			detailViewUrl: '',
			pager: null,
			filter: '',
			sortedBy: '',
			shownItems: '',
			sortedOrder: ''
		}, options||{});
	},	
	changeView: function(mode)
	{				
		this.currentView = mode;
		this.options.shownItems = document.getElementById("shownItems").checked;
		this.reloadView();		
	},
	clearSort: function() {
		this.options.sortedBy = "";
		this.options.sortedOrder = "";
	},

	reloadView: function(resetPaging) {		
		this.hideLoading();
		this.showLoading();	
		if (this.transport) this.transport.abort();
		var pars = "";
		if (this.options.pager != null)
		{
			if (resetPaging) {
				pars = "&page=1";
			} else {
				pars = "&page=" + this.options.pager.getCurrentPage();
			}
		}
		if (this.options.filter != '')
		{
			pars = pars + "&query=" + encodeURIComponent($(this.options.filter).value);
		}
		pars = pars + "&sortedBy=" + encodeURIComponent(this.options.sortedBy) + "&sortedOrder=" + encodeURIComponent(this.options.sortedOrder);
		pars = pars + "&shownItems="+this.options.shownItems;
		switch (this.currentView)
		{
			case "list":
				this.transport = (new Ajax.Updater({success: this.options.viewHolderId}, root + "/" + this.options.listViewUrl + pars, {method: 'get', onComplete:function(){ViewManager.getInstance().updateComplete();}, onFailure:function(){ViewManager.getInstance().hideLoading();}, onTimeout:function(){ViewManager.getInstance().hideLoading();}})).transport;
				break;
			case "grid":
				this.transport = (new Ajax.Updater({success: this.options.viewHolderId}, root + "/" + this.options.gridViewUrl + pars, {method: 'get', onComplete:function(){ViewManager.getInstance().updateComplete();}, onFailure:function(){ViewManager.getInstance().hideLoading();}, onTimeout:function(){ViewManager.getInstance().hideLoading();}})).transport;
				break;
			case "detail":
				this.transport = (new Ajax.Updater({success: this.options.viewHolderId}, root + "/" + this.options.detailViewUrl + pars, {method: 'get', onComplete:function(){ViewManager.getInstance().updateComplete();}, onFailure:function(){ViewManager.getInstance().hideLoading();}, onTimeout:function(){ViewManager.getInstance().hideLoading();}})).transport;
				break;		
		}
				
	},
	
	updateComplete: function() {
		ViewManager.getInstance().hideLoading();
		var response = new String(this.transport.responseText);
		response.extractScripts().map(function(script) { 
			return eval(script.replace("<!--", "").replace("// -->", ""));
		});				
	},
	
	updateSorted: function(tableId) {
		var rels = Neighborrow.Utils.getElementsByRel($(tableId), 'td', 'sort');
		for (i=0; i<rels.length; i++) {
			var className = "";
			if (rels[i].getAttribute("value") == this.options.sortedBy) {
				className = this.options.sortedOrder;
			}
			rels[i].innerHTML = "<a href=\"javascript:void(0);\" onclick=\"ViewManager.getInstance().sort('" + rels[i].getAttribute("value") + "')\" class=\""+ className +"\">" + rels[i].innerHTML + "</a>";
		}		
	},
	
	sort: function(val) {
		if (this.options.sortedBy != val) {
			this.options.sortedBy = val;
			this.options.sortedOrder = "asc";
		}
		else {
			if (this.options.sortedOrder == "asc") this.options.sortedOrder = "desc";
			else this.options.sortedOrder = "asc";
		}

		this.reloadView();
	},
	hideLoading: function()
	{
		if (this.loader) this.loader.hide();
		this.loader = null;
	},

	showLoading: function()
	{
		this.loader = new Neighborrow.Controls.Loader({element: $(this.options.viewHolderId), loadingClass: 'loading', loadingIconClass: 'loading_icon'});
		this.loader.show();	
	}
};

var cvInstance = new Neighborrow.Controls.ViewManager.Instance();
Neighborrow.Controls.ViewManager.getInstance = function() {
	return cvInstance;
}
var ViewManager = Neighborrow.Controls.ViewManager;

/***************** Neighborrow.Controls.Loader *******************/
Neighborrow.Controls.Loader = Class.create();
Neighborrow.Controls.Loader.prototype = {
	initialize: function(options) {
		this.options = Neighborrow.Utils.setOptions({
			element: null,
			loadingClass: null,
			loadingIconClass: null
		}, options||{});
		
		this.ajax_loading = null;
		this.ajax_loading_icon = null;
	},

	show: function() {

		this.ajax_loading = document.createElement("div");
		this.ajax_loading.className = this.options.loadingClass;

		this.ajax_loading_icon = document.createElement("div");
		this.ajax_loading_icon.className = this.options.loadingIconClass;		
		
		this.options.element.parentNode.appendChild(this.ajax_loading);
		this.options.element.parentNode.appendChild(this.ajax_loading_icon);
				
		x = Neighborrow.Utils.getLeft(this.options.element);
		y = Neighborrow.Utils.getTop(this.options.element);
		
		Neighborrow.Utils.setLeft(this.ajax_loading_icon, x);
		Neighborrow.Utils.setTop(this.ajax_loading_icon, y);
		
		Neighborrow.Utils.setLeft(this.ajax_loading, x);
		Neighborrow.Utils.setTop(this.ajax_loading, y);

		this.ajax_loading_icon.style.width = this.ajax_loading.style.width = Neighborrow.Utils.getWidth(this.options.element) + "px";
		this.ajax_loading_icon.style.height = this.ajax_loading.style.height = Neighborrow.Utils.getHeight(this.options.element) + "px";

	},

	hide: function() {
		this.options.element.parentNode.removeChild(this.ajax_loading);
		this.options.element.parentNode.removeChild(this.ajax_loading_icon);
	}
}