/**
 * @author jus
 */

var baseURL = 'http://www.readme.cc/';

var Bookshelf = Class.create();
Bookshelf.prototype = {
	initialize: function(element) {
		this.element = element;
		this.options = Object.extend({
			//state: [[3, 2, 5, false], [false, false, false, false], [1, 2, 1, false]],
			draggableClass: 'draggable',
			dropsiteClass: 'dropsite',
			hoverClass: 'hoverclass',
			requestUrl: ''+ baseURL +'ajax/fileadmin/scripts/bookshelfgetter.php',
			mainElement: 'bookshelf_main',
			loadingElement: 'bookshelf_loading',
			containerElement: 'bookshelf_container',
			temporaryPanelMainElement: 'temporary_panel_main',
			temporaryPanelContainerElement: 'temporary_panel_container',
			temporaryPanelLoadingElement: 'temporary_panel_loading_element'
		}, arguments[1] || {});
		this.drags = [];
		this.drops = [];
		this.request = null;
		this.json = null;
		this.temporaryPanelLoaded = false;
	},
	init: function() {
		var _this = this;

		this.drags._each(function(el) {el.destroy();});
		this.drags.clear();

		var divs = document.getElementsByClassName(this.options.draggableClass);
		for (var i = 0; i < divs.length; i++) {
			this.drags.push(
				new Draggable(divs[i], {
						ghosting: Prototype.Browser.Opera ? false : true,
						revert: true
				}));
		}

		this.drops._each(function(el){Droppables.remove(el);});
		this.drops = document.getElementsByClassName(this.options.dropsiteClass);
		for (var i = 0; i < this.drops.length; i++)
		{
			Droppables.add(this.drops[i], {
				// accept makes at least ff3@linux slow, we don't have any other kinds of droppables
				// here so we accept everything 
				// accept: _this.options.draggableClass,
				hoverclass: _this.options.hoverClass,
				onDrop:function(element, dropon, event) {

					var dragFromTrash = (element.parentNode.id == 'trash');
					var dropToTrash = (dropon.parentNode.id == 'trash');

					var pElement = element.parentNode;
					var pDropon = dropon.parentNode;

					function toNormalArray(obj) {
						var arr = [];
						for (var i = 0; i < obj.length; i++)
							arr[i] = obj[i];
						return arr;
					}

					if (_this.json) {
						var temp_drags = $(_this.options.temporaryPanelContainerElement).getElementsByClassName(_this.options.draggableClass);
						var temp_drops = $(_this.options.temporaryPanelContainerElement).getElementsByClassName(_this.options.dropsiteClass);

						// in ff3 the above 2 lines return something very strange						
						temp_drags = toNormalArray(temp_drags);
						temp_drops = toNormalArray(temp_drops);

						// removing item from source
						var item = null;
						if (dragFromTrash) { // remove from trash
							item = _this.trashItem;
							_this.trashItem = false;
						} else if (temp_drags.indexOf(element) == -1) { //remove from bookshelf
							item = _this.json.state[pElement.parentNode.rowIndex][pElement.cellIndex];
							_this.json.state[pElement.parentNode.rowIndex][pElement.cellIndex] = false;
						} else { // remove from temp panel
							item = _this.json.temp[pElement.cellIndex]
							_this.json.temp[pElement.cellIndex] = false;
						}

						// putting item to destination
						if (dropToTrash) { // put to trash
							_this.trashItem = item;
						} else if (temp_drops.indexOf(dropon) == -1) { // put to bookshelf
							_this.json.state[pDropon.parentNode.rowIndex][pDropon.cellIndex] = item;
						} else { // put to temp panel
							_this.json.temp[pDropon.cellIndex] = item;
						}
					}

					// window.xxx = Object.toJSON(_this.json);
					// setTimeout('alert(window.xxx)', 500);

					var cDropon = pDropon.replaceChild(element, dropon);
					pElement.appendChild(cDropon);

					element.setStyle({
								left: '0px',
								top: '0px'
					});

					// if (dropToTrash) // save immediately
					_this.savePage();
				}
			});
		}
	},
	loadPage: function(pageNum) {
		var _this = this;
		if (this.request == null) {
			if (Prototype.Browser.IE) {
				$(this.options.mainElement).setStyle({overflow: 'hidden'});
			}
			$(this.options.loadingElement).show();

// var xjson = Object.toJSON(_this.json);
			var temp_page_num = this.json ? this.json.temp_page_num : 1;
			this.request = new Ajax.Request(this.options.requestUrl + '&page_num=' + pageNum + '&temp_page_num=' + temp_page_num,
			{
				method: 'get',
				requestHeaders: {'X-JSON': Object.toJSON(_this.json)},
				onSuccess: function(transport, json){
					if (json) {
						_this.json = json;
// alert('pre:'+ xjson + '\npost:'+ Object.toJSON(_this.json));
						$(_this.options.containerElement).innerHTML = transport.responseText;
						_this.init();
					} else {
						alert(transport.responseText);
					}
				},
				onComplete: function(transport){
					$(_this.options.loadingElement).hide();
					if (Prototype.Browser.IE) {
						$(_this.options.mainElement).setStyle({overflow: 'visible'});
					}

					_this.request = null;
				},
				onException: function(request, ex){
					$(_this.options.loadingElement).hide();
					if (Prototype.Browser.IE) {
						$(_this.options.mainElement).setStyle({overflow: 'visible'});
					}

					_this.request = null;
				}
			});

			if (!this.temporaryPanelLoaded) {
				this.loadTemporaryPanel(1);
			}
		}
	},
	loadTemporaryPanel: function(pageNum) {
		var _this = this;

		this.temporaryPanelLoaded = true;
		if (Prototype.Browser.IE) {
			$(this.options.temporaryPanelMainElement).setStyle({overflow: 'hidden'});
		}
		$(this.options.temporaryPanelLoadingElement).show();
// var xjson = Object.toJSON(_this.json);
		var page_num = this.json ? this.json.page_num : 1;
		new Ajax.Request(this.options.requestUrl + '&temp=1&temp_page_num='+pageNum + '&page_num='+ page_num,
		{
			method: 'get',
			requestHeaders: {'X-JSON': Object.toJSON(_this.json)},
			onSuccess: function(transport, json){
				_this.json = json;
				$(_this.options.temporaryPanelContainerElement).innerHTML = transport.responseText;
// alert('pre:'+ xjson + '\npost:'+ Object.toJSON(_this.json));
				_this.init();
			},
			onComplete: function(transport){
				$(_this.options.temporaryPanelLoadingElement).hide();
				if (Prototype.Browser.IE) {
					$(_this.options.temporaryPanelMainElement).setStyle({overflow: 'visible'});
				}
			},
			onException: function(request, ex){
				$(_this.options.temporaryPanelLoadingElement).hide();
				if (Prototype.Browser.IE) {
					$(_this.options.temporaryPanelMainElement).setStyle({overflow: 'visible'});
				}

				_this.temporaryPanelLoaded = false;
			}
		});
	},
	savePage: function() {
		var _this = this;
		if (this.request == null) {
			if (Prototype.Browser.IE) {
				$(this.options.mainElement).setStyle({overflow: 'hidden'});
			}
			$(this.options.loadingElement).show();
			$(this.options.temporaryPanelLoadingElement).show();

//			alert(Object.toJSON(_this.json))
			var url = this.options.requestUrl + '&save=1';

			// if having item in trash this will be deleted now!
			if (this.trashItem) {
				url += '&deleteItem='+ this.trashItem;
				this.clearTrash();
			}
			this.request = new Ajax.Request(url,
			{
				method: 'get',
				requestHeaders: {'X-JSON': Object.toJSON(_this.json)},
				onSuccess: function(transport){
					if (transport.responseText)
						alert(transport.responseText);
				},
				onComplete: function(transport){
					$(_this.options.loadingElement).hide();
					$(_this.options.temporaryPanelLoadingElement).hide();
					if (Prototype.Browser.IE) {
						$(_this.options.mainElement).setStyle({overflow: 'visible'});
					}

					_this.request = null;
				},
				onException: function(request, ex){
					$(_this.options.loadingElement).hide();
					$(_this.options.temporaryPanelLoadingElement).hide();
					if (Prototype.Browser.IE) {
						$(_this.options.mainElement).setStyle({overflow: 'visible'});
					}

					_this.request = null;
				}
			});
		}
	},
	clearTrash: function() {
		delete this.trashItem;
		document.getElementById("trash").innerHTML = '<div class="dropsite" style="position:relative"></div>';
		this.init();
	}
}

