// függőségek
if ("undefined" == typeof AITIA) {
	alert("AITIA include missing!");
}

if ("undefined" == typeof AITIA_EVENT) {
	alert("AITIA_EVENT include missing!");
}

// többszörös include
if ("undefined" != typeof AITIA_DND) {
	 alert("AITIA_DND multiple insert!");
}

AITIA_DND = 1;

/**
 * Javascript osztály drag'n'drop megvalósítására.
 * drag objektumok paraméterei:
 *  - start(drag, event) függvény, drag induláskor fut le
 *  - move(drag, event) függvény, drag közben fut
 *  - end(drag, event) függvény, drag végén fut le
 *  - movable true|false mozog-e az objektum az egérrel
 * 
 * drop objektumok paraméterei:
 *  - drop(drag, drop, event) függvény, drag objektum ejtésekor fut le
 *  - hover(drag, drop, event) függvény, drag objektum drop felett lebegtetésekor fut le
 *  - leave(drop, event) függvény, drop feletti lebegtetés végén fut le
 *  - hoverclass string a drop elem css osztálya, ha van felette drag objektum
 * 
 * observer objektum függvényei:
 *  - start(drag, event) függvény, drag induláskor fut le
 *  - move(drag, event) függvény, drag közben fut
 *  - end(drag, event) függvény, drag végén fut le, drop objektum nékül
 *  - drop(drag, drop, event) függvény, drag objektum ejtésekor fut le
 *  - hover(drag, drop, event) függvény, drag objektum drop felett lebegtetésekor fut le
 *  - leave(drop, event) függvény, drop feletti lebegtetés végén fut le
 */
Aitia.Dnd = {
	drops: [],
	drags: [],
	lastDrag: null,
	lastDrop: null,
	observer: null,
	_dragsCnt: 0,
	
	addDrag: function(o, options) {
		o = $(o);
		if(o.options) {
			for(attr in options) {
				o.options[attr] = options[attr];
			}
		} else {
			o.options = options;
		}
		//o.onmousedown = this._startDrag(o);
		o.drag1 = function(e) {Aitia.Dnd._startDrag(e, o);};
		Aitia.Event.addEvent(o, 'mousedown', o.drag1);
		this._dragsCnt++;
	},
	
	removeDrag: function(o) {
		try {
			o = $(o);
			o.onmousedown = {};
			Aitia.Event.removeEvent(o, 'mousedown', o.drag1);
		}
		catch(e) {}
	},

	addDrop: function(o, options) {
		o = $(o);
		if(o.options) {
			for(attr in options) {
				o.options[attr] = options[attr];
			}
		} else {
			o.options = options;
		}
		o.drop1 = function(e) {Aitia.Dnd._startDrop(e, o);};
		Aitia.Event.addEvent(o, 'mouseup', o.drop1);
		o.drop2 =  function(e) {Aitia.Dnd._startHover(e, o);};
		Aitia.Event.addEvent(o, 'mouseover', o.drop2);
		o.drop3 =  function(e) {Aitia.Dnd._endHover(e, o);};
		Aitia.Event.addEvent(o, 'mouseout', o.drop3);
	},

	removeDrop: function(o) {
		o = $(o);
		if(o.drop1) {
			Aitia.Event.removeEvent(o, 'mouseup', o.drop1);
			Aitia.Event.removeEvent(o, 'mouseover', o.drop2);
			Aitia.Event.removeEvent(o, 'mouseout', o.drop3);
		}
	},

	addObserver: function(o) {
		this.observer = o;
	},
	
	_startDrag: function(ev, o) {
		if(!ev) {
			ev = window.event;
		}
		document.onmousemove = this._dragging;
		document.body.onmouseup = this._endDrag;
		var drag = $(o);
		Aitia.Dnd.lastDrag = drag;
		if(Aitia.Dnd.observer) {
			if(Aitia.Dnd.observer.start) {
				Aitia.Dnd.observer.start(drag, ev);
			}
		}
		if(drag.options.start) {
			drag.options.start(drag, ev);
		}
	},
	
	_dragging: function(ev) {
		if(!ev) {
			ev = window.event;
		}

		var sel ;
		if(document.selection && document.selection.empty){
			document.selection.empty() ;
		} else if(window.getSelection) {
			sel=window.getSelection();
			if(sel && sel.removeAllRanges) {
				sel.removeAllRanges();
			}
		}

		if(Aitia.Dnd.lastDrag) {
			var drag = Aitia.Dnd.lastDrag;
			if(Aitia.Dnd.observer) {
				if(Aitia.Dnd.observer.move) {
					Aitia.Dnd.observer.move(drag, ev);
				}
			}
			if(drag.options.movable) {
				drag.setStyle({	left: 10+(ev.pageX | ev.clientX)+'px', 
												top: 10+(ev.pageY | ev.clientY)+'px', 
												position: 'absolute', 
												zIndex: '1000'});
			}
			if(drag.options.move) {
				drag.options.move(drag, ev);
			}
		}
	},
	
	_endDrag: function(ev) {
		if(!ev) {
			ev = window.event;
		}
		document.onmousemove = {};
		document.body.onmouseup = {};
		if(Aitia.Dnd.lastDrag) {
			var drag = Aitia.Dnd.lastDrag;
			if(Aitia.Dnd.observer) {
				if(Aitia.Dnd.observer.end) {
					Aitia.Dnd.observer.end(drag, ev);
				}
			}
			if(drag.options.end) {
				drag.options.end(drag, ev);
			}
			if(drag.options.movable) {
				//drag.options.end(drag.element, ev);
			}
			Aitia.Dnd.lastDrag = null;
			if(Aitia.Dnd.lastDrop) {
				if(Aitia.Dnd.lastDrop.options.hoverclass) {
					Aitia.Dnd.lastDrop.removeClassName(Aitia.Dnd.lastDrop.options.hoverclass);
				}
				Aitia.Dnd.lastDrop = null;
			}
		}
	},
	
	_startDrop: function(ev, o) {
		if(!ev) {
			ev = window.event;
		}
		if(Aitia.Dnd.lastDrag) {
			Aitia.Event.stopPropagation(ev);
			var drop = $(o);
			if(drop.options.accept) {
				if(!drag.hasClassName(drop.options.accept)) {
					return;
				}
			}
			var drag = Aitia.Dnd.lastDrag;
			if(drop != drag) {
				if(Aitia.Dnd.observer) {
					if(Aitia.Dnd.observer.drop) {
						Aitia.Dnd.observer.drop(drag, drop, ev);
					}
				}
				if(drop.options.drop) {
					drop.options.drop(drag, drop, ev);
				}
			} else {
				Aitia.Dnd._endDrag(ev);
			}
			Aitia.Dnd.lastDrag = null;
		}
	},
	
	_startHover: function(ev, o) {
		if(!ev) {
			ev = window.event;
		}
		var drop = $(o);
		if(Aitia.Dnd.lastDrag) {
			var drag = Aitia.Dnd.lastDrag;
			if(drop.options.hoverclass) {
				drop.addClassName(drop.options.hoverclass);
			}
			if(Aitia.Dnd.observer) {
				if(Aitia.Dnd.observer.hover) {
					Aitia.Dnd.observer.hover(drag, drop, ev);
				}
			}
			if(drop.options.hover) {
				drop.options.hover(drag, drop, ev);
			}
		}
		Aitia.Dnd.lastDrop = drop;
	},
	
	_endHover: function(ev, o) {
		if(!ev) {
			ev = window.event;
		}
		if(Aitia.Dnd.lastDrop) {
			if(Aitia.Dnd.lastDrop.options.hoverclass) {
				Aitia.Dnd.lastDrop.removeClassName(Aitia.Dnd.lastDrop.options.hoverclass);
			}
			if(Aitia.Dnd.lastDrop.options.leave) {
				Aitia.Dnd.lastDrop.options.leave(Aitia.Dnd.lastDrop, ev);
			}
			if(Aitia.Dnd.observer) {
				if(Aitia.Dnd.observer.leave) {
					Aitia.Dnd.observer.leave(Aitia.Dnd.lastDrop, ev);
				}
			}
			Aitia.Dnd.lastDrop = null;
		}
	}
};