rememberlist = {
	container: null,
	waster: null,
	queue: [],
	preventLinkFunction: function(e){e.stop();},
	
	init: function() {
		this.container = $('rememberlist');
		this.waster = this.container.getFirst().getNext().getFirst();
		while(!this.waster.hasClass('recycle') && this.waster.getNext()) this.waster = this.waster.getNext();
		this.members = $('rememberlist_members').get('html').replace(/ /g, '').replace(/\n/g, '').replace(/\r/g, '');
		rlDND.addEvent('over', this.dragOver.bind(this));
		rlDND.addEvent('out', this.dragOut.bind(this));
		rlDND.addEvent('drop', this.drop.bind(this));
		this.registerDrop(this.waster, 0);
		this.registerDrop(this.container, 1);
		var w,h,c,r;
		w = this.container.getSize();
		h = w.y;
		w = w.x;
		this.params = this.container.getChildren('div')[0].getChildren('div');
		c = 1;
		r = this.params[0];
		while(r.getNext() && r.getNext().getCoordinates().top == r.getCoordinates().top) {
			r = r.getNext();
			c++;
		}
		r = this.params.length/c;
		this.params = 'w='+w+'&h='+h+'&c='+c+'&r='+r+'&id=';
		
		this.req = new Request({url: '/lib/ajax.rememberlist.php', onSuccess: this.replaceIt.bind(this), link: 'chain'});
		new Request({url: '/lib/ajax.rememberlist.strings.php', onSuccess: this.start.bind(this)}).send();
	},
	start: function(t, xml) {
		t = t.split("\n");
		this.addstrings = [];
		this.removestrings = [];
		t.each(function(v,k,o){
			v = v.split("|");
			this.addstrings.push(v[0]);
			this.removestrings.push(v[1]);
		}, this);
	},
	add: function(element) {
		if(this.container == null) return false;
		this.members += element+"|";
		this.queue.push(element);
		this.req.send(this.params+element);
		return false;
	},
	remove: function(element) {
		if(this.container == null) return false;
		var replace = new RegExp("/\|"+element+"\|/");
		this.members = this.members.replace(replace, "|").replace(/\|\|/g, "|");
		this.queue.push(element);
		this.req.send(this.params+element);
		return false;
	},
	replaceIt: function(t, xml) {
		var x = new Element('div');
		x.innerHTML = t;
		x = x.getFirst();
		this.container.innerHTML = x.innerHTML;
		x = this.queue.pop();
		var classname = 'rememberlist_'+x;
		if(document.all && !navigator.appVersion.match(/MSIE 8/)) x = $$('a');
		else x = document.getElementsByName(classname);
		$each(x, function(v,k,o){
			v = $(v);
			if(v.get('name') != classname) return;
			var i, j = "_"+v.getFirst().src.split('/').pop().split('_').pop().split('.').shift()+".";
			if(j == this.addstrings[0]) {
				i = this.addstrings;
				j = this.removestrings;
			} else {
				i = this.removestrings;
				j = this.addstrings;
			}
			for(var y=0; y<i.length; y++) {
				t = new RegExp(i[y], 'g');
				v.innerHTML = v.innerHTML.replace(t, j[y]);
			}
		}, this);
		this.waster = this.container.getFirst().getNext().getFirst();
		while(!this.waster.hasClass('recycle') && this.waster.getNext()) this.waster = this.waster.getNext();
		rlDND.updateDropElement(this.waster, 0);
	},
	registerDrag: function(e, id, thumb) {
		rlDND.registerDragElement(e, id, this.createDragIcon.bind({src: thumb}));
		e.getElements('a').each(function(v){
			if(v.get('name') == 'rememberlist_'+id)
				v.addEvent('mousedown', rememberlist.preventLinkFunction);
		});
	},
	registerDrop: function(e, id) {
		rlDND.registerDropElement(e, id);
	},
	createDragIcon: function(src, dest) {
		new Element('img').set('src', this.src).injectInside(dest.setStyles({width: 'auto', height: 'auto'}));
	},
	dragOver: function(e) {
		if(e.dragElement != null && e.dropElement.element == this.container)
			this.container.addClass('dndOver');
	},
	dragOut: function(e) {
		if(e.dropElement.element == this.container)
			this.container.removeClass('dndOver');
	},
	drop: function(e) {
		if(e.dropElement) {
			if(e.dragElement != null && e.dropElement.element == this.container && this.members.indexOf("|"+e.dragElement.id+"|") < 0)
				return this.add(e.dragElement.id);
			if(e.dragElement != null && e.dropElement.element == this.waster && this.members.indexOf("|"+e.dragElement.id+"|") >= 0)
				return this.remove(e.dragElement.id);
		}
		return true;
	}
};
var dragNdropManager = new Class({
	Implements: Events,	
	registeredDropElements: {},
	actualDragElement: null,
	actualDropElement: null,
	initialize: function() {
		
	},
	registerDragElement: function(elem, id, createIcon) {
		new dragElement(elem, id, this, createIcon);
	},
	registerDropElement: function(elem, id) {
		if(this.registeredDropElements[id]) return true;
		this.registeredDropElements[id] = new dropElement(elem, id, this);
	},
	updateDropElement: function(elem, id) {
		if(this.registeredDropElements[id])
			this.registeredDropElements[id].element = elem;
	},
	check: function(x, y) {
		$each(this.registeredDropElements, function(v){v.check(this.x, this.y);}, {x: x, y: y});
	},
	over: function(e) {
		this.actualDropElement = e;
		this.fireEvent('over', {dragElement: this.actualDragElement, dropElement: this.actualDropElement});
	},
	out: function(e) {
		this.fireEvent('out', {dragElement: this.actualDragElement, dropElement: e});
		if(this.actualDropElement == e)
			this.actualDropElement = null;
	},
	drop: function(e) {
		if(this.actualDragElement != null) {
			this.fireEvent('drop', {dragElement: this.actualDragElement, dropElement: this.actualDropElement});
			if(this.actualDropElement != null)
				this.out(this.actualDropElement);
			this.actualDragElement = null;
		}
	}
});
var dragElement = new Class({
	initialize: function(e, id, m, createIcon) {
		this.element = $(e);
		this.id = id;
		this.manager = m;
		
		this.icon = new Element('div').setStyles({width: 1, height: 1});
		if(createIcon) createIcon(e, this.icon);
		var dummi = new Element('div').setStyles({position: 'absolute', overflow: 'hidden', height: 1, width: 1}).injectInside(document.body);
		this.icon.setStyles({position: 'absolute', top: 1, left: 1}).injectInside(dummi);
		this.iconCoords = this.icon.getCoordinates();
		this.iconCoords.offLeft = this.iconCoords.width/2;
		this.iconCoords.offTop = this.iconCoords.height/2;
		this.icon.dispose();
		dummi.destroy();
		this.mouse_x = -1;
		this.mouse_y = -1;
		this.moved = false;
		this.move = this.move.bind(this);
		this.drop = this.drop.bind(this);
		this.element.addEvent('mousedown', this.drag.bind(this));
	},
	drag: function(e) {
		e.preventDefault();
		this.moved = false;
		this.manager.actualDragElement = this;
		this.mouse_x = e.page.x;
		this.mouse_y = e.page.y;
		this.updateIcon();
		$(document.body).addEvent('mousemove', this.move);
		$(document.body).addEvent('mouseup', this.drop);
	},
	move: function(e) {
		e.preventDefault();
		if(!this.moved) {
			this.moved = true;
			this.icon.setStyle('z-index', 10).injectInside(document.body);
		}
		this.mouse_x = e.page.x;
		this.mouse_y = e.page.y;
		this.updateIcon();
		this.manager.check(this.mouse_x, this.mouse_y);
	},
	drop: function(e) {
		e.preventDefault();
		$(document.body).removeEvent('mousemove', this.move);
		$(document.body).removeEvent('mouseup', this.drop);
		this.manager.drop();
		this.icon.dispose();
		if(!this.moved) {
			var fl = this.fireLinks.bind({fl: this.fireLinks, x: this.mouse_x, y: this.mouse_y})
			fl(this.element);
		}
	},
	updateIcon: function() {
		this.icon.setStyles({top: this.mouse_y-this.iconCoords.offTop, left: this.mouse_x-this.iconCoords.offLeft});
	},
	fireLinks: function(e) {
		if(e.get('tag') == 'a') {
			var dim = e.getCoordinates();
			if(this.x > dim.left && this.x < dim.left+dim.width && this.y > dim.top && this.y < dim.top+dim.height)
				window.location = e.get('href');
		}
		e.getChildren().each(this.fl.bind({fl: this.fl, x: this.x, y: this.y}));
	}
});
var dropElement = new Class({
	coords: {},
	stateHover: false,
	initialize: function(e, id, m) {
		this.element = $(e);
		this.id = id;
		this.manager = m;
	},
	over: function(e) {
		this.manager.over(this);
		this.stateHover = true;
	},
	out: function(e) {
		this.manager.out(this);
		this.stateHover = false;
	},
	check: function(x, y) {
		this.coords = this.element.getCoordinates();
		this.coords.right = this.coords.left+this.coords.width;
		this.coords.bottom = this.coords.top+this.coords.height;
		
		if(!this.stateHover && x > this.coords.left && x < this.coords.right && y > this.coords.top && y < this.coords.bottom)
			this.over();
		if(this.stateHover && ( x < this.coords.left || x > this.coords.right || y < this.coords.top || y > this.coords.bottom) )
			this.out();
	}
});


rlDND = new dragNdropManager();

$(window).addEvent('load', rememberlist.init.bind(rememberlist));
