var CtGrid_Row = Class.create({

	element: null,
	selected: false,

	initialize: function(htmlElement) {
		this.element = $(htmlElement);
		this.selected = false;


		this.element.observe('mouseover', this.mouseoverHandler.bindAsEventListener(this));
		this.element.observe('mouseout', this.mouseoutHandler.bindAsEventListener(this));
		this.element.observe('click', this.clickHandler.bindAsEventListener(this));
	},



	mouseoverHandler: function(event) {
		if (!this.selected) {
			this.element.addClassName('ctGrid-row-hover');
		}
	},

	mouseoutHandler: function(event) {
		if (!this.selected) {
			this.element.removeClassName('ctGrid-row-hover');
		}
	},


	clickHandler: function(event) {
		if (this.selected) {
			this.element.removeClassName('ctGrid-row-select');
			this.selected = false;
		} else {
			this.element.addClassName('ctGrid-row-select');
			this.selected = true;
		}
	},




	x: null

});

var CtGrid_MassAction = Class.create({

	element: null,
	ctGrid: null,

	checkAll: null,
	checkOne: [],
	submitAction: [],
	submitActionContainer: null,

	initialize: function(ctGrid) {
		this.ctGrid = ctGrid;
		this.element = this.ctGrid.element;

		this.reassembly();
	},

	reassembly: function() {
		this.submitActionContainer = this.element.down('.ctGrid-massAction-submitAction-container');
		if (!this.submitActionContainer) {
			return;
		}

		this.submitAction = this.element.select('.ctGrid-massAction-submitAction');
		this.checkAll = this.element.down('.ctGrid-massAction-checkAll');
		this.checkOne = this.element.select('.ctGrid-massAction-checkOne');

		this.updateSubmitActionContainer();

		if (this.checkOne.length == 0 || this.submitAction.length == 0) {
			return;
		}

		if (!this.checkAll) {
			this.checkAll = {};
			this.checkAll.checked = false;
		}

		for (var i = 0; i < this.checkOne.length; i++) {
			this.checkOne[i].observe('click', this.checkOneChangeHandler.bindAsEventListener(this));
		}

		this.checkAll.observe('click', this.checkAllChangeHandler.bindAsEventListener(this));


		for (var i = 0; i < this.submitAction.length; i++) {
			this.submitAction[i].observe('click', this.submitActionClickHandler.bindAsEventListener(this, this.submitAction[i]));
		}
	},

	checkAllChangeHandler: function(event) {
		for (var i = 0; i < this.checkOne.length; i++) {
			this.checkOne[i].checked = this.checkAll.checked;
		}

		this.updateSubmitActionContainer();
	},


	checkOneChangeHandler: function(event) {
		this.checkAll.checked = false;
		for (var i = 0; i < this.checkOne.length; i++) {
			if (this.checkOne[i].checked) {
				this.checkAll.checked = true;
				break;
			}
		}

		this.updateSubmitActionContainer();
	},

	updateSubmitActionContainer: function() {
		if (this.checkAll.checked) {
			this.submitActionContainer.show();
		} else {
			this.submitActionContainer.hide();
		}
	},


	submitActionClickHandler: function(event, submitAction) {
		Event.stop(event);
		this.ctGrid.deletePopup.show('Are you sure?', this.deleteConfirmYes.bind(this, submitAction));
	},

	deleteConfirmYes: function(submitAction) {
//		this.ctGrid.processingStart();

		var customInputs = this.element.select('.ctGrid-massAction-input');

		var params = Form.serializeElements(this.checkOne);
		if (params.length > 0) {
			params = params + '&';
		}

		params = params + Form.serializeElements(customInputs);

		var request = CtPage.getRequest(this.ctGrid.id, 'iframe');
		request.url = submitAction.readAttribute('href');
		if (request.url.indexOf('?') !== -1) {
			request.url += '&' + params;
		} else {
			request.url += '?' + params;
		}
		request.send();
	},

	x: null
});

var CtGrid_PopupMassAction = Class.create(CtGrid_MassAction, {

	initialize: function($super, ctGrid) {
		$super(ctGrid);
	},

	reassembly: function($super) {
		$super();
		this.popupAction = this.element.select('.ctGrid-massAction-popupAction');
		for (var i = 0; i < this.popupAction.length; i++) {
			if (this.popupAction[i].hasClassName('confirm-action')) {
				this.popupAction[i].observe('click', this.confirmAction.bindAsEventListener(this, this.popupAction[i]));
			} else {
				this.popupAction[i].observe('click', this.popupActionClickHandler.bindAsEventListener(this, this.popupAction[i]));
			}
		}
	},

	popupActionClickHandler: function(popupAction) {
		var params = Form.serializeElements(this.checkOne);

		var url = popupAction.readAttribute('href');
		if (url.indexOf('?') !== -1) {
			url += '&' + params;
		} else {
			url += '?' + params;
		}
		CtPopup.showUrl(url, 'roundBlock roundBlock4 dark');
	},

	confirmAction: function (event, popupAction) {
		Event.stop(event);
		this.ctGrid.deletePopup.show('Are you sure?', this.popupActionClickHandler.bind(this, popupAction));
	}
});

var CtGrid = Class.create(CtComponent_Abstract, {
	rows: [],
	config: null,
	massAction: null,
	status: null,
	deletePopup: null,

	locker: null,


	_processingStartDelegates: [],
	_processingFinishDelegates: [],



	initialize: function(htmlElement) {
		this.element = $(htmlElement);
		this.id = this.element.identify();
		this.status = new CtComponent_Message();
		this.massAction = new CtGrid_MassAction(this);
		this.deletePopup = new CtComponent_ConfirmBox();
		this.popupMassAction = new CtGrid_PopupMassAction(this);

		this.reassembly();

		this.locker = new CtComponent_BlockLocker(this.element);

		CtPage.addComponent(this);
	},


	reassembly: function() {
		this.element.insert({top: this.status.element});

		try {
			var configElement = this.element.down('.ctGrid-config');
			if (!configElement) {
				throw '';
			}

			this.config = configElement.innerHTML.evalJSON();
			configElement.remove();

		} catch (exc) {
			throw 'Config is required for grid ' + this.id;
		}

		var rows = this.element.select('.ctGrid-row');
		this.rows = [];
		for (var i = 0; i < rows.length; i++) {
			this.rows.push(new CtGrid_Row(rows[i]));
		}


		var deleteButtons = this.element.select('.ctGrid-deleteButton');
		for (var i = 0; i < deleteButtons.length; i++) {
			deleteButtons[i].observe('click', this.deleteClickHandler.bindAsEventListener(this, deleteButtons[i]));
		}
		var sortButtons = this.element.select('.ctGrid-sortButton');
		for (var i = 0; i < sortButtons.length; i++) {
			sortButtons[i].observe('click', this.sortClickHandler.bindAsEventListener(this, sortButtons[i]));
		}
		var ajaxButtons = this.element.select('.ctGrid-ajaxButton');
		for (var i = 0; i < ajaxButtons.length; i++) {
			ajaxButtons[i].observe('click', this.ajaxClickHandler.bindAsEventListener(this, ajaxButtons[i]));
		}



		var pagerList = this.element.select('.ctGrid-pager');
		pagerList.each(function(pager) {
			var pagerButtons = pager.select('a');
			for (var i = 0; i < pagerButtons.length; i++) {
				pagerButtons[i].observe('click', this.pagerClickHandler.bindAsEventListener(this, pagerButtons[i]));
			}
		}.bind(this));

		var perpageList = this.element.select('.ctGrid-perPage');
		perpageList.each(function(perpage) {
			var perpageButtons = perpage.select('a');
			for (var i = 0; i < perpageButtons.length; i++) {
				perpageButtons[i].observe('click', this.pagerClickHandler.bindAsEventListener(this, perpageButtons[i]));
			}
		}.bind(this));

		this.element.select('.js').each(function(element) {element.removeClassName('js')});
		this.element.select('.nojs').each(function(element) {element.remove()});
	},


	deleteClickHandler: function(event, deleteButton) {
		Event.stop(event);

		try {
			var params = deleteButton.readAttribute('rel').evalJSON();
			if (params.length != 2 && params.length != 3) {
				throw '';
			}
		} catch (exc) {
			throw "Two parameters must be provided (as JSON array) for every delete button: 'id' and 'name'";
			return;
		}

		var recordName = params[1].length > 20 ? params[1].substr(0, 17) + '...' : params[1];

		this.deletePopup.show('Are you sure to delete "' + recordName + '"?', this.deleteConfirmYes.bind(this, params[0], params[2]));
	},


	deleteConfirmYes: function(value, additional) {

		this.processingStart();

		var request = CtPage.getRequest(this.id, 'iframe');
		if (this.config['delete'].action.indexOf('?') !== -1) {
			request.url = this.config['delete'].action + '&' + this.config['delete'].name + '=' + value;
		} else {
			request.url = this.config['delete'].action + '?' + this.config['delete'].name + '=' + value;
		}
		if (additional) {
			request.url += '&' + Object.toQueryString(additional);
		}
		request.send();
	},


	ajaxClickHandler: function(event, ajaxButton) {
		Event.stop(event);
		this.processingStart();

		var request = CtPage.getRequest(this.id, 'iframe');
		request.url = ajaxButton.readAttribute('href');
		request.send();
	},


	sortClickHandler: function(event, sortButton) {
		Event.stop(event);
		this.processingStart();

		var request = CtPage.getRequest(this.id, 'iframe');
		if (this.config['sort'].action.indexOf('?') !== -1) {
			request.url = this.config['sort'].action + '&' + this.config['sort'].name + '=' + sortButton.readAttribute('rel');
		} else {
			request.url = this.config['sort'].action + '?' + this.config['sort'].name + '=' + sortButton.readAttribute('rel');
		}
		request.send();
	},


	pagerClickHandler: function(event, pagerButton) {
		Event.stop(event);

		this.processingStart();
		var request = CtPage.getRequest(this.id, 'iframe');

		if (pagerButton.match('.ctGrid-pager a')) {
			if (this.config['pager'].action.indexOf('?') !== -1) {
				request.url = this.config['pager'].action
							+ '&'
							+ this.config['pager'].name
							+ '='
							+ pagerButton.readAttribute('rel');
			} else {
				request.url = this.config['pager'].action
							+ '?'
							+ this.config['pager'].name
							+ '='
							+ pagerButton.readAttribute('rel');
			}
		} else {
			if (this.config['perpage'].action.indexOf('?') !== -1) {
				request.url = this.config['perpage'].action + '&' + this.config.perpage.name + '=' + pagerButton.readAttribute('rel');
			} else {
				request.url = this.config['perpage'].action + '?' + this.config.perpage.name + '=' + pagerButton.readAttribute('rel');
			}
		}
		
		request.send();
	},



	refresh: function(response) {
		if (response && response.content) {
			this.element.insert({after: this.status.element});
			this.element.update(response.content);
			this.reassembly();
			this.massAction.reassembly();
		}

		if (response.json && response.json && response.json.messages) {
			this.status.show(response.json.messages);
		} else {
			this.status.hide();
		}

		this.processingFinish();
	},


	processingStart: function() {
		this.locker.show();

		for (var i = 0; i < this._processingStartDelegates.length; i++) {
			this._processingStartDelegates[i]();
		}
 	},


	processingFinish: function(response) {
		this.locker.hide();

		for (var i = 0; i < this._processingFinishDelegates.length; i++) {
			this._processingFinishDelegates[i](response);
		}
 	},


	addProcessingStartCallback: function(callback) {
		this._processingStartDelegates.push(callback);
	},


	addProcessingFinishCallback: function(callback) {
		this._processingFinishDelegates.push(callback);
	},

	x: null

});



var CtGrid_Factory = new (Class.create({
	initialize: function() {
		Event.observe(window, 'load', function() { this.refresh() }.bind(this));
	},

	refresh: function(htmlElement) {
		var elements = [];
		if (htmlElement) {
			elements = $(htmlElement).select('div.ctGrid');
		} else {
			elements = $$('div.ctGrid');
		}
		for (var i = 0; i < elements.length; i++) {
			elements[i].removeClassName('ctGrid');
			new CtGrid(elements[i]);
		}
	}
}));



CtPage.registerScript("CtGrid");
