/******************************************************************************
* sdsDragDrop.js
*******************************************************************************
Drag and Drop Manager
*******************************************************************************
*                                                                             *
* Copyright 2008									                          *
*                                                                             *
******************************************************************************/
function SdsDragAndDropObject(type, data, html)
{
	this._type = type;
	this._data = data;
	this._html = html;
}

SdsDragAndDropObject.prototype.getType = function()
{
	return this._type;
}

SdsDragAndDropObject.prototype.getData = function()
{
	return this._data;
}
SdsDragAndDropObject.prototype.getHtml = function()
{
	return this._html;
}
function SdsAbstractDragAndDropTarget(rootElement)
{
	if(rootElement) {
		this._rootElement = rootElement;
	}
}

SdsAbstractDragAndDropTarget.prototype.isAlive = function()
{
	return true;
}

SdsAbstractDragAndDropTarget.prototype.acceptsType = function(type)
{
	alert("la méthode 'acceptsType' de la cible du drag and drop n'est pas implémentée\n");
	return false;
}
SdsAbstractDragAndDropTarget.prototype.accepts = function(dragObject, element)
{
	alert("la méthode 'accepts' de la cible du drag and drop n'est pas implémentée\n");
	return false;
}

SdsAbstractDragAndDropTarget.prototype.receives = function(dragAndDropObject)
{
	alert("la méthode 'receives' de la cible du drag and drop n'est pas implémentée\n");
	return;
}

function SdsDragAndDropManager()
{
	this._targets = [];
	this._documents = [];
	this._bestManager = null;
	this._acceptedTypes = {};
}

SdsDragAndDropManager.prototype.getBestManager = function()
{
	if(this._bestManager) return this._bestManager;
	var f = window;
	if(f.frames.parent.sdsDragAndDropManager) {
		f = f.frames.parent;
	} else {
		while(f.frames.parent != f && f.frames.parent.sdsDragAndDropManager) {
			f = frames.parent;
		}
	}
	return f.sdsDragAndDropManager;
}

SdsDragAndDropManager.prototype.hasTargetForType = function(type)
{
	if(this._acceptedTypes[type]) return true;
	for(var i=0;i<this._targets.length;i++) {
		var target = this._targets[i];
		try {
			if(target.acceptsType(type)) {
				this._acceptedTypes[type] = true;
				return true;
			}
		} catch(e) {
			this.removeAllUnloadedTargets();
		}
	}
	return false;
}

SdsDragAndDropManager.prototype.start = function(ev, dragObject)
{
	var manager = this.getBestManager();
	if(manager != this) return manager.start(dragObject);
	this._dragObject = dragObject;
	var de = this._dragElement = document.createElement("div");
	document.body.appendChild(this._dragElement);
	de.style.backgroundColor = "#C0C0C0";
	de.style.position = "absolute";
	de.style.border = "1px solid black";
	de.style.padding = "4px";
	de.innerHTML = dragObject.getHtml();
	de.style.display = "block";

	this.addEvent(document.frames.top.document.body, "mousemove", this.dragmove);
	this.addEvent(document.frames.top.document.body, "mouseup", this.mouseup);
	for(var i=0;i<document.frames.length;i++) {
		var frame = document.frames[i];
		this.addEvent(frame.document.body, "mousemove", this.dragmove);
		this.addEvent(frame.document.body, "mouseup", this.mouseup);
	}
}

SdsDragAndDropManager.prototype.dragmove = function(ev)
{
    ev || (ev = window.event);
    var element = document.all ? ev.srcElement : ev.currentTarget;
	var manager = sdsDragAndDropManager.getBestManager();
	return manager.ondragmove(ev, element);
}


SdsDragAndDropManager.prototype.mouseup = function(ev)
{
    ev || (ev = window.event);
    var element = document.all ? ev.srcElement : ev.currentTarget;
	var manager = sdsDragAndDropManager.getBestManager();
	return manager.onmouseup(ev, element);
}

SdsDragAndDropManager.prototype.ondragmove = function(ev, element)
{
	var de = this._dragElement;
	de.style.left = ev.screenX - document.frames.top.screenLeft + 2;
	de.style.top = ev.screenY - document.frames.top.screenTop - 10;
	de.style.display = "block";
	for(var i=0;i<this._targets.length;i++) {
		var target = this._targets[i];
		try {
			target.accepts(this._dragObject, element);
		} catch(e) {
			this.removeAllUnloadedTargets();
		}
	}
}

SdsDragAndDropManager.prototype.onmouseup = function(ev, element)
{
	this.removeEvent(document.frames.top.document.body, "mousemove", this.dragmove);
	this.removeEvent(document.frames.top.document.body, "mouseup", this.mouseup);
	for(var i=0;i<document.frames.length;i++) {
		var frame = document.frames[i];
		this.removeEvent(frame.document.body, "mousemove", this.dragmove);
		this.removeEvent(frame.document.body, "mouseup", this.mouseup);
	}
	if(this._dragElement != null) {
		this._dragElement.style.display = "none";
	}
	for(var i=0;i<this._targets.length;i++) {
		var target = this._targets[i];
		try {
			target.receives(this._dragObject, element);
		} catch(e) {
			this.removeAllUnloadedTargets();
		}
	}
	this._dragObject = null;
}

SdsDragAndDropManager.prototype.stop = function()
{
	var manager = this.getBestManager();
	if(manager != this) return manager.stop();
}

SdsDragAndDropManager.prototype.addTarget = function(target, doc)
{
	var manager = this.getBestManager();
	if(manager != this) return manager.addTarget(target, doc);
	this._targets[this._targets.length] = target;
	var found = false;
	for(var i=0;i<this._documents.length;i++) {
		if(this._documents[i] == doc) found = true;
	}
	if(!found) {
		this.addEvent(doc.frames.self, "unload", this.unload);
	}
	this._documents[this._documents.length] = doc;
}

SdsDragAndDropManager.prototype.unload = function(ev)
{
	var manager = sdsDragAndDropManager.getBestManager();
	manager.removeAllUnloadedTargets();
}

SdsDragAndDropManager.prototype.removeAllUnloadedTargets = function()
{
	var targets = [];
	var documents = [];
	for(var i=0;i<this._targets.length;i++) {
		var target = this._targets[i];
		var doc = this._documents[i];
		try {
			target.isAlive();
			targets[targets.length] = target;
			documents[documents.length] = doc;
		} catch(e) {
		}
	}
	this._targets = targets;
	this._documents = documents;
	this._acceptedTypes = {};
}

SdsDragAndDropManager.prototype.addEvent = function(element, evname, func) 
{
    if (element.attachEvent) { // IE
        element.attachEvent("on" + evname, func);
    } else if (element.addEventListener) { // Gecko / W3C
        element.addEventListener(evname, func, true);
    } else {
        element["on" + evname] = func;
    }
}

SdsDragAndDropManager.prototype.removeEvent = function(element, evname, func) 
{
	if (element.detachEvent) { // IE
		element.detachEvent("on" + evname, func);
	} else if (element.removeEventListener) { // Gecko / W3C
		element.removeEventListener(evname, func, true);
	} else {
		element["on" + evname] = null;
	}
}

window.sdsDragAndDropManager = new SdsDragAndDropManager();