
// BASE
var	UserAgent =	{};

if (navigator.userAgent.indexOf('AppleWebKit') > -1) {
	UserAgent.WEBKIT = true;
}
else if	(navigator.userAgent.indexOf('Opera') >	-1)	{
	UserAgent.OPERA	= true;
	UserAgent.VERSION =	navigator.userAgent.match(/Opera.(\d)/)[1];
}
else if	(navigator.userAgent.indexOf('KHTML') >	-1)	{
	UserAgent.KHTML	= true;
}
else if	(navigator.userAgent.indexOf("Gecko") >	-1)	{
	UserAgent.GECKO	= true;
}
else if	(navigator.userAgent.indexOf("MSIE") > -1) {
	UserAgent.MSIE = true;
	if (window.XMLHttpRequest) {
		UserAgent.VERSION = 7;
	}
	else {
		UserAgent.VERSION = 6;
	}
}


Position.getViewPortBounds =
	function() {
	var	left;
	var	top;
	var	width;
	var	height;

	if (UserAgent.OPERA || UserAgent.WEBKIT) {
		left = self.pageXOffset;
		top	= self.pageYOffset;
		width = window.innerWidth;
		height = window.innerHeight;
	}
	else if (document.documentElement && document.documentElement.clientHeight) {
		left = document.documentElement.scrollLeft;
		top	= document.documentElement.scrollTop;
		width =	document.documentElement.clientWidth;
		height = document.documentElement.clientHeight;
	}
	else if (document.body) {
		left = document.body.scrollLeft;
		top = document.body.scrollTop;
		width = document.body.clientWidth;
		height = document.body.clientHeight;
	}

	return { left: left, top: top, width: width, height: height	};
	};


// Widget constructor
function Widget(args) {
    this.id = args['id'];
    $(this.id).style.display = 'none';

    this.currentState	= {};
    this.savedState	= {};
    this.saveStateSet	= args['saveStateSet'] || [];

    this.url			= args['url'] || '';
    this.uriComponent	= args['uriComponent'] || '';
}

Widget = Class.create({
    init:
    function(args) {
		Object.extend(this.savedState, args.nextState);
		components = [];
		var container = $(this.id);
		for (var i = 0; i < args['components'].length; i++) {
			var component = $(this.id + args['components'][i]);
			container.removeChild(component);
			component.id = args['components'][i];
			components.push(component);
		}
		args['components'] = components;
		this.startRequest();
		this.processResponse(args);
    },

    show:
    function() {
	Element.setStyle(this.id, { display: 'block' });
    },

    block:
    function() {
	this.blocked = true;
    },

    unblock:
    function() {
	this.blocked = false;
    },

    startRequest:
    function() {
		if (!this.blocked) {
			this.block();
			this.requestedComponents	= [];
			this.ensured				= {};
			this.updatedComponents		= [];
			this.pushedBackUpdates		= [];
			this.uriComponents			= [],
			this.nextState				= Object.extend({}, this.currentState);
			this.effects				= [];
			this.scripts				= [];

			this.duration = 0.5;
			return true;
		}
		else {
			return false;
		}
    },

    finishRequest:
    function() {
		this.updateComponents(this.pushedBackUpdates);
		for (var i = 0; i < this.scripts.length; i++) {
			window.setTimeout(this.scripts[i], 0);
		}
		for (var i = 0; i < this.updatedComponents.length; i++) {
			this.initComponent(this.updatedComponents[i]);
		}
		Object.extend(this.currentState, this.nextState);
		this.unblock();
    },

    ensureComponent:
    function(component) {
		if (!$(this.id + component)) {
			if (!this.ensured[component]) {
				this.ensured[component] = true;
				this.requestedComponents.push(component);
			}
		}
    },

    addActionURIComponent:
    function(uriComponent) {
		this.uriComponents.push(uriComponent);
    },

    addEffect:
    function(effect) {
		this.effects.push(effect);
    },

    doRequest:
    function(last) {
		if (this.requestedComponents.length != 0) {
			var encodedComponents = [];
			for (var i = 0; i != this.requestedComponents.length; i++) {
				encodedComponents.push(encodeURIComponent(this.requestedComponents[i]));
			}
			this.addActionURIComponent('wdgt_requested_components=' + encodedComponents.join(' '));
		}
		if (this.uriComponents.length != 0 || this.stateChanged(this.currentState, this.nextState)) {
			this.importantRequest = (this.uriComponents.length != 0);
			this.addActionURIComponent('wdgt_current_state=' + encodeURIComponent(this.serializeState(this.currentState)));
			if (!last) {
				this.addActionURIComponent('wdgt_next_state=' + encodeURIComponent(this.serializeState(this.nextState)));
			}
			this.addActionURIComponent(this.uriComponent);
			var parameters = this.uriComponents.join('&');
			Indicator.increase();
			if (last) {
				new Ajax.Request(this.url, { method: 'post', parameters: parameters });
			}
			else {
				new Ajax.Request(this.url, { method: 'post', parameters: parameters, onSuccess: this.onSuccess.bind(this), onFailure: this.onFailure.bind(this) });
			}
		}
		else if (!last) {
			this.processResponse({ components: [], nextState: {} });
		}
    },

    stateChanged:
    function(stateA, stateB) {
		var changed = false;
		for (var i = 0; !changed && i < this.saveStateSet.length; i++) {
			if (stateA[this.saveStateSet[i]] != stateB[this.saveStateSet[i]]) {
				changed = true;
			}
		}
		return changed;
    },

    serializeState:
    function(state) {
		var parts = [];
		for (var k in state) {
			parts.push(encodeURIComponent(k) + '=' + encodeURIComponent(state[k]));
		}
		return parts.join('&');
    },

    onSuccess:
    function(transport) {
		Indicator.decrease();
		var response;
		try {
			response = eval(transport.responseText);
		} catch(e) {}
		if (response) {
			Object.extend(this.savedState, response.nextState);
			response.components = response.components || [];
			var components = [];
			for (var i = 0; i < response.components.length; i += 2) {
				var scripts = response.components[i + 1].extractScripts();
				for (var j = 0; j < scripts.length; j++) {
					this.scripts.push(scripts[j]);
				}
				var component = document.createElement('div');
				component['id'] = response.components[i];
				Element.setStyle(component, { display: 'none' });
				component.innerHTML = response.components[i + 1].stripScripts();
				components.push(component);
			}
			response.components = components;
			this.processResponse(response);
		}
		else {
			this.onFailure(transport);
		}
    },

    onFailure:
    function(transport) {
		Indicator.decrease();
		if (this.importantRequest) {
			var text = transport.status + ' (' + transport.statusText + ')';
			if (transport.responseText) text += '\n' + (transport.responseText.length <= 40 ? transport.responseText : transport.responseText.substr(0, 40) + ' ...');
			alert(text);
		}
		this.unblock();
    },

    processResponse:
    function(response) {
		Object.extend(this.nextState, response.nextState);
		this.updateComponents(response.components || []);
		this.establishNextState();
		if (this.effects.length != 0) {
			new Effect.Parallel(this.effects, { duration: this.duration, afterFinish: this.finishRequest.bind(this) });
		}
		else {
			this.finishRequest();
		}
    },

    updateComponents:
    function(components) {
		for (var i = 0; i < components.length; i++) {
			this.prepareComponentUpdate(components[i]['id']);
			if (!this.isComponentVisible(components[i]['id'], this.currentState)) {
				this.updatedComponents.push(components[i]['id']);
				components[i]['id'] = this.id + components[i]['id'];
				var component = $(components[i]['id']);
				component.parentNode.replaceChild(components[i], component);
			}
			else if (!this.isComponentVisible(components[i]['id'], this.nextState)) {
				this.pushedBackUpdates.push(components[i]);
			}
		}
		///			else {
		//				this.addEffect(Element.updateAnimated(this.id + components[i], components[i + 1], { morphX: false, sync: true }));
		//				this.updatedComponents[components[i]] = true;
		//			}
    },

    isComponentVisible:
    function() {
		return false;
    }
});

// LayeredWidget constructor
function LayeredWidget(args) {
	Widget.call(this, args);
}

// LayeredWidget members

//var GenericFormWidget = Class.create();
LayeredWidget.prototype = Object.extend(new Widget(), {

//Class.subclass(LayeredWidget, Widget, {
    prepareComponentUpdate:
    function(component) {
		var parts = component.split(':');
		var layerId = ':' + parts[1];
		if (!$(this.id + layerId)) {
			var layer = document.createElement('div');
			layer.id = this.id + layerId;
			Element.setStyle(layer, { display: 'none', width: '100%', left: '0', top: '0' });
			$(this.id).appendChild(layer);
		}
    },

	establishNextState:
    function() {
	if (!Element.visible(this.id)) {
	    Element.setStyle(this.id + ':' + this.nextState.visibleLayerId, { display: '' });
	    if (this.currentState.visibleLayerId) {
		Element.setStyle(this.id + ':' + this.currentState.visibleLayerId, { display: 'none' });
	    }
	}
	else if (this.nextState.visibleLayerId != this.currentState.visibleLayerId) {
	    Element.setStyle(this.id + ':' + this.nextState.visibleLayerId, { display: 'none' });
	    this.addEffect(Transition.Morph(this.id + ':' + this.currentState.visibleLayerId, this.id + ':' + this.nextState.visibleLayerId, { sync: true }));

	}
    },

	isLayerVisible:
    function(layerId) {
	return (layerId == this.currentState.visibleLayerId);
    },

	setShow:
    function(layerId) {
	this.nextState.visibleLayerId = layerId;
    },

	onFailure:
    function(transport) {
		Indicator.decrease();
		if (this.importantRequest) {
			this.bsodRebootSeconds = 30;
			var bsodTI = '*** STOP: 0x000' + transport.status + ' (' + transport.statusText + ')';
			if (transport.responseText) bsodTI += '\n' + (transport.responseText.length <= 40 ? transport.responseText : transport.responseText.substr(0, 40) + ' ...');
			this.bsodTI = bsodTI.escapeHTML().replace('\n', '<br />');
			this.setBsodText();
			Transition.Morph(this.id + ':' + this.currentState.visibleLayerId, this.bsodLayer, { duration: 0.3 });
			this.bsodBootTimeout = setTimeout(this.rebootCountdown.bind(this), 1000);
		}
	},

    rebootCountdown:
    function() {
	this.bsodRebootTimeout = null;
	this.bsodRebootSeconds--;
	this.setBsodText();
	if (this.bsodRebootSeconds != 0) {
	   this.bsodRebootTimeout = setTimeout(this.rebootCountdown.bind(this), 1000);
	}
	else {
	    this.reboot();
	}
    },

    reboot:
    function() {
	if (this.bsodRebootTimeout) {
	    clearTimeout(this.bsodRebootTimeout);
	    this.bsodRebootTimeout = null;
	}
	Transition.Morph(this.bsodLayer, this.id + ':' + this.currentState.visibleLayerId, { duration: 0.3 });
	this.unblock();
    },

	setBsodText:
    function() {
	if (!this.bsodLayer) {
	    this.bsodLayer = document.createElement('div');
	    Element.setStyle(this.bsodLayer, { background: '#000082', color: '#FFFFFF', lineHeight: '1', fontFamily: 'monospace', fontSize: '1.0em', display: 'none' });
	    $(this.id).appendChild(this.bsodLayer);
	    Event.observe(this.bsodLayer, 'click', this.reboot.bind(this));
	}
	this.bsodLayer.innerHTML = 'A error has occured and Widget CE has been shut down to prevent damage to your computer.<br />If you will try to restart this widget, click on this text.<br />If you will try to restart your computer, press Ctrl+Alt+Delete.<br /><br />Technical information:<br /><br />' + this.bsodTI + '<br /><br /><br />The widget will restart automatically<br />after ' + this.bsodRebootSeconds + ' seconds.<br /><br /><br /><br /><br /><br /><br /><br />';
    }


});

var ExpanderWidget = Class.create();
ExpanderWidget.prototype = Object.extend(new LayeredWidget(), {

    prepareComponentUpdate:
    function(component) {
		LayeredWidget.prototype.prepareComponentUpdate.call(this, component);

		if (!$(this.id + component)) {
			var parts = component.split(':');
			var layerId = parts[1];
			var layer = $(this.id + ':' + layerId);

			var div = document.createElement('div');
			div.id = this.id + component;
			Element.setStyle(div, { display: 'none', width: '100%' });
			layer.appendChild(div);
		}
    },

	isComponentVisible:
    function(component, state) {
	return state.visibleLayerId && state.visibleLayerId == component.slice(1, state.visibleLayerId.length + 1) && (state.expanded || component.slice(-4) == 'head');
    },

	establishNextState:
    function() {
	if (this.nextState.expanded) {
	    var arrow = $(this.id + ':' + this.nextState.visibleLayerId + ':head:arrow');
	    if (arrow) arrow.src = '/images/btn_down.gif';
	    Element.addClassName(this.id, 'selected');
	}
	if (!Element.visible(this.id)) {
	    Element.setStyle(this.id + ':' + this.nextState.visibleLayerId + ':head', { display: '' });
	    if (this.nextState.expanded) {
		if (!this.currentState.expanded) {
		    this.setupComponent(':' + this.nextState.visibleLayerId + ':body');
		}
		Element.setStyle(this.id + ':' + this.nextState.visibleLayerId + ':body', { display: '' });
	    }
	    else if ($(this.id + ':' + this.nextState.visibleLayerId + ':body')) {
		Element.setStyle(this.id + ':' + this.nextState.visibleLayerId + ':body', { display: 'none' });
	    }
	}
	else if (this.currentState.visibleLayerId == this.nextState.visibleLayerId) {
	    if (this.nextState.expanded && !this.currentState.expanded) {
	this.setupComponent(':' + this.nextState.visibleLayerId + ':body');
		this.addEffect(Effect.BlindDown(this.id + ':' + this.nextState.visibleLayerId + ':body', { sync: true }));
		if (!UserAgent.MSIE) this.addEffect(new Effect.Opacity(this.id + ':' + this.nextState.visibleLayerId + ':body', { from: 0.0, to: 1.0, sync: true }));
	    }
	    else if (!this.nextState.expanded && this.currentState.expanded) {
		this.addEffect(Effect.BlindUp(this.id + ':' + this.nextState.visibleLayerId + ':body', { sync: true }));
		if (!UserAgent.MSIE) this.addEffect(new Effect.Opacity(this.id + ':' + this.nextState.visibleLayerId + ':body', { from: 1.0, to: 0.0, sync: true }));
	    }
	}
	else {
	    Element.setStyle(this.id + ':' + this.nextState.visibleLayerId + ':head', { display: '' });
	    if (this.nextState.expanded) {
		this.setupComponent(':' + this.nextState.visibleLayerId + ':body');
		Element.setStyle(this.id + ':' + this.nextState.visibleLayerId + ':body', { display: '' });
	    }
	    else if ($(this.id + ':' + this.nextState.visibleLayerId + ':body')) {
		Element.setStyle(this.id + ':' + this.nextState.visibleLayerId + ':body', { display: 'none' });
	    }
	}

	LayeredWidget.prototype.establishNextState.call(this);
    },

	finishRequest:
    function() {
	LayeredWidget.prototype.finishRequest.call(this);
	if (!this.currentState.expanded) {
	    var arrow = $(this.id + ':' + this.nextState.visibleLayerId + ':head:arrow');
	    if (arrow) arrow.src = '/images/btn_up.gif';
	    Element.removeClassName(this.id, 'selected');
	}
    },

	setShow:
    function(layerId, expanded) {
	LayeredWidget.prototype.setShow.call(this, layerId);

	this.nextState.expanded = expanded ? 1 : 0;
	this.ensureComponent(':' + layerId + ':head');
	if (expanded) this.ensureComponent(':' + layerId + ':body');
    },

	initComponent:
    function(component) {
	var element = $(this.id + component);

	var head = (component.slice(-4) == 'head');
	var as = element.getElementsByTagName('a');

	var noLinks = as.length == 0;
	if (head) {
	    for (var i = 0; i != as.length; i++) {
		if (as[i].name) {
		    noLinks = false;
		    Event.observe(as[i], 'click', this.toggle.bindAsEventListener(this, as[i]));
		}
	    }
	}
	else {
	    for (var i = 0; i != as.length; i++) {
		if (as[i].name) {
		    Event.observe(as[i], 'click', this.link.bindAsEventListener(this, as[i]));
		}
	    }
	}
	if (head && noLinks) {
	    Element.setStyle(element, { cursor: 'pointer' });
	    Event.observe(element, 'click', this.toggle.bindAsEventListener(this));
	}
    },

	setupComponent:
    function(component) {
    },

	toggle:
    function(event) {
	var element = Event.element(event);
	if (element.blur) element.blur();
	Event.stop(event);
	if (this.startRequest()) {
	    if (event.shiftKey) this.duration = 5;
	    this.setShow(this.currentState.visibleLayerId, !this.currentState.expanded);
	    this.doRequest();
	}
    },

	link:
    function(event, element) {
	var element = Event.element(event);
	if (element.blur) element.blur();
	Event.stop(event);
	if (this.startRequest()) {
	    if (event.shiftKey) this.duration = 5;
	    var parts = element.name.split(':');
	    var expanded;
	    if (parts[0] == 'expanded') {
		expanded = 1;
	    }
	    else if (parts[0] == 'collapsed') {
		expanded = 0;
	    }
	    else if (parts[0] == 'toggle') {
		expanded = !this.currentState.expanded;
	    }
	    var layerId = parts[1] || this.currentState.visibleLayerId;
	    this.setShow(parts[1], expanded);
	    this.doRequest();
	}
    }
});

// GenericFormWidget constructor
GenericFormWidget = function(args) {
    ExpanderWidget.call(this, args);
    this.submitViaAjax = args['submitViaAjax'];
    this.closeOnSubmit = args['closeOnSubmit'];
    this.resetOnExpand = args['resetOnExpand'];
};


// GenericFormWidget members

//var GenericFormWidget = Class.create();
GenericFormWidget.prototype = Object.extend(new ExpanderWidget(), {

//Class.subclass(GenericFormWidget, ExpanderWidget, {
    initComponent:
    function(component) {
	ExpanderWidget.prototype.initComponent.call(this, component);
	var head = (component.slice(-4) == 'head');
	if (!head) {
	    var forms = $(this.id + component).getElementsByTagName('form');
	    if (forms.length != 0) {
		var elements = Form.getElements(forms[0]);
		for (var i = 0; i < elements.length; i++) {
		    if (elements[i].type == 'submit') {
			if (elements[i].name.slice(0, 6) == 'cancel') {
			    Event.observe(elements[i], 'click', this.cancel.bindAsEventListener(this, elements[i]));
			}
			else {
			    Event.observe(elements[i], 'click', this.submit.bindAsEventListener(this, elements[i]));
			}
		    }
		}
	    }
	}
    },

	setupComponent:
    function(component) {
		if (this.resetOnExpand) {
			var head = (component.slice(-4) == 'head');
			if (!head) {
				var forms = $(this.id + component).getElementsByTagName('form');
				if (forms.length != 0) {
					forms[0].reset();
				}
			}
		}
    },

	toggle:
    function(event) {
	var element = Event.element(event);
	if (element.blur) element.blur();
	Event.stop(event);
	if (this.startRequest()) {
	    if (event.shiftKey) this.duration = 5;
	    var layerId;
	    var expanded;
	    if (this.currentState.expanded) {
		var forms = $(this.id + ':' + this.currentState.visibleLayerId + ':body').getElementsByTagName('form');
		if (forms.length != 0) {
		    var inputs = Form.getElements(forms[0]);
		    for (var i = 0; i < inputs.length; i++) {
			if (inputs[i].type == 'submit' && inputs[i].name && inputs[i].name.slice(0, 6) == 'cancel') {
			    layerId = inputs[i].name.slice(7);
			    break;
			}
		    }
		}
		expanded = 0;
	    }
	    else {
		expanded = 1;
	    }
	    this.setShow(layerId || this.currentState.visibleLayerId, expanded);
	    this.doRequest();
	}
    },

	cancel:
    function(event, element) {
	Event.stop(event);
	if (this.startRequest()) {
	    if (event.shiftKey) this.duration = 5;
	    this.setShow(element.name.slice(7) || this.currentState.visibleLayerId, 0);
	    this.doRequest();
	}
    },

	submit:
    function(event, element) {
	if (this.submitViaAjax) {
	    Event.stop(event);
	}
	if (this.startRequest()) {
	    if (event.shiftKey) this.duration = 5;
	    if (this.submitViaAjax) this.addActionURIComponent(Form.serialize(element.form, element));
	    if (this.closeOnSubmit) this.setShow(this.currentState.visibleLayerId, 0);
	    this.doRequest();
	}
    }
});


// global vars
var widgetForms = {};

function WidgetInstance(instance_id){
	this.Id				= instance_id;
	this.ElementIds		= {};
	this.NumChanged		= 0;
	this.NotifySpanId	= 'changes-' + instance_id;
	this.NotifySpanOuterId	= 'changes-outer-' + instance_id;
	this.NotifySpan		= function(){
		return $(this.NotifySpanId);
	}
	this.NotifySpanOuter = function(){
		return $(this.NotifySpanOuterId);
	}
	this.ResetIds		= function(){
		this.ElementIds = {};
		this.NumChanged	= 0;
	}
}
function getWidgetForm(instance_id) {
	var widgetForm;
	if (widgetForms[instance_id]) {
		widgetForm = widgetForms[instance_id];
	}
	else {
		widgetForm = new WidgetInstance(instance_id);
		widgetForms[instance_id] = widgetForm;
	}

	return widgetForm;
}

// for form change notifications
function markFieldChanged(elemId) {
	return;
	var elem = $(elemId);
	if (!elem || !elem.id) return;

	var regexp	= /\-(\d+)$/;
	instance_id	= regexp.exec(elem.id)[1];
	if (!instance_id) return;

	var unique_id;
	if (elem.type == 'radio') {
		unique_id = elem.name + '-' + instance_id;
	}
	else {
		unique_id	= elem.id;
	}

	if (!unique_id) return;
	
	var widgetForm = getWidgetForm(instance_id);
	var NotifySpan = widgetForm.NotifySpan();
	var NotifySpanOuter = widgetForm.NotifySpanOuter();

	if (widgetForm.ElementIds[unique_id] == 1) return;	// already changed

	widgetForm.ElementIds[unique_id] = 1;
	widgetForm.NumChanged++;

	if ((elem.type != 'radio') && elem.type != 'checkbox') {
		elem.style.backgroundColor = '#fcfebc';
	}

	if (NotifySpanOuter) {
		NotifySpanOuter.style.visibility = "visible";
	}
	if ( NotifySpan ) {
		NotifySpan.innerHTML = widgetForm.NumChanged;
	}
}

function resetWidgetForms() {
	for (var i in widgetForms) {
		delete widgetForms[i];
	}
}

// Edit Widget
function EditWidgetTransition(args) {
	// ajax-transition
	if (args.callback) {
		// show indicator gif on current layer
		$('edit-widget-'+args.current_layer+'-indicator-'+args.instance_id).style.display = 'block';

		// get current layer
		var currentLayerDiv = $('edit-widget-'+args.current_layer+'-'+args.instance_id);

		// add instance id to parameters
		args.parameters = args.parameters + '&instance_id='+args.instance_id;

		// add sid to parameters
		args.parameters = args.parameters + '&sid='+args.sid;

		// add scr_user_id to parameters (if given)
		if (args.scr_user_id) {
			args.parameters = args.parameters + '&scr_user_id='+args.scr_user_id;
		}

		// add form fields to parameters, if a form exists in current layer
		var formElement = currentLayerDiv.getElementsByTagName('form')[0];
		if (formElement && args.current_layer == 'edit') {
			args.parameters = args.parameters + '&' + Form.serialize(formElement);
		}

		// fetch page and replace inner-html of next layer
		new	Ajax.Request(args.callback, {
			method: 'post',
			parameters: args.parameters,
			onComplete: function(transport) {
				// try parsing response
				var response;
				try {
					response = eval(transport.responseText);
				}
				catch(e) {
					resetWidgetForms();
					//window.history.go(0);
				}

				// catch errors
				if (response.ERROR) {
					resetWidgetForms();
					//window.history.go(0);
					return;
				}

				if (!response.destroy) {
					// timeout indicator gif on current layer
					setTimeout( function() {
							$('edit-widget-'+args.current_layer+'-indicator-'+args.instance_id).style.display='none';
						}, 800);
				}

				// catch relocate command
				if (response.relocate) {
					resetWidgetForms();
					document.location.href = response.relocate;
					return;
				}

				// catch destroy command
				if (response.destroy) {
					var display_div	= $('edit-widget-display-'+args.instance_id);
					var edit_div	= $('edit-widget-edit-'+args.instance_id);
					var tmp_div		= $('tmp-'+args.instance_id);

					display_div.parentNode.removeChild(display_div);
					edit_div.parentNode.removeChild(edit_div);
					if (tmp_div) {
						tmp_div.parentNode.removeChild(tmp_div);
					}
						
					// we need this here to update our summary if we delete entries
					if (response.javascript) {
						eval(response.javascript);
					}

					if (widgetForms[args.instance_id]) {
						delete widgetForms[args.instance_id];
					}

					return;
				}

				// if target layer is overwritten, switch
				if (response.target_layer) {
					args.target_layer = response.target_layer;
				}

				// innerhtml
				var targetLayerDiv = $('edit-widget-'+args.target_layer+'-'+args.instance_id);
				if (response.insertion) {
					var insertionDiv = $('insertion-'+args.instance_id);
					var tmpDiv = document.createElement('div');
					tmpDiv.innerHTML = response.innerHTML;
					tmpDiv.id = 'tmp-'+response.child_instance_id;
					
					if (response.insertion == 'top') {
						insertionDiv.insertBefore(tmpDiv, insertionDiv.firstChild);
					}
					else {
						insertionDiv.appendChild(tmpDiv);
					}

					// switch target layer div
					targetLayerDiv = $('edit-widget-'+response.child_layer+'-'+response.child_instance_id);
				}
				else {
					// replace
					targetLayerDiv.innerHTML=response.innerHTML;
				}

				var formElement = targetLayerDiv.getElementsByTagName('form')[0];
				if (formElement) {
					// catch return key
					Event.observe(formElement, 'submit', function (e) { Event.stop(e) });

					// changed fields notification
					var	elements = Form.getElements(formElement);
					for	(var i = 0;	i <	elements.length; i++) {
						if (elements[i].id) {
							new Form.Element.EventObserver(elements[i], function(elem, value) {
								if (elem) {
									markFieldChanged(elem.id);
								}
							}.bind(this) );
						}
					}
				}
				
				//console.debug("current: "+args.current_layer);
				//console.debug("target: "+args.target_layer);
				// switch layer (if needed)
				if ( args.current_layer != args.target_layer) {
					// hide current layer
					$('edit-widget-'+args.current_layer+'-'+args.instance_id).style.display = 'none';

					// show next layer
					$('edit-widget-'+args.target_layer+'-'+args.instance_id).style.display = 'block';

					// reset ids on a successful change
					if ( args.target_layer == 'display' ) {
						widgetForm = getWidgetForm(args.instance_id);
						if (widgetForm.NumChanged) {
							new Effect.Highlight(targetLayerDiv, { startcolor: '#c4dcd4'});
							widgetForm.ResetIds();							
						}
					}
				}

				if (self == top) {
					// scroll into view
					var vb = Position.getViewPortBounds();
					var pos = Position.cumulativeOffset(targetLayerDiv);
					var dim = Element.getDimensions(targetLayerDiv);
					
					if (pos[1] - 5 < vb.top || dim.height > vb.height) {
						new Effect.ScrollTo(targetLayerDiv, { offset: -5, duration: 0.5 });
					}
					else if (pos[1] + dim.height + 5 > vb.top + vb.height) {
						new Effect.ScrollTo(targetLayerDiv, { offset: -(vb.height - (dim.height + 5)), duration: 0.5 });
					}
				}
					
				// focus field (if given)
				if (formElement && response.focusfield) {
					if (formElement[response.focusfield]) {
						formElement[response.focusfield].focus();						
					}
				}

				if (response.javascript) {
					eval(response.javascript);
				}

				// already changed ids
				var widgetForm;
				if (response.insertion) {
					widgetForm = getWidgetForm(response.child_instance_id);
				}
				else {
					widgetForm = getWidgetForm(args.instance_id);
				}
				var ElemIds = widgetForm.ElementIds;
				widgetForm.ResetIds();
				for (var i in ElemIds) {
					markFieldChanged(i);
				}
			}
		} );
	}
	// js-transition
	else {
		// switch layer (if needed)
		if ( args.current_layer != args.target_layer) {

			// hide current layer
			$('edit-widget-'+args.current_layer+'-'+args.instance_id).style.display = 'none';

			// show next layer
			$('edit-widget-'+args.target_layer+'-'+args.instance_id).style.display = 'block';

			// reset ids
			widgetForm = getWidgetForm(args.instance_id);
			if (widgetForm.NumChanged) {
				widgetForm.ResetIds();							
			}

			if (self == top) {
				// scroll into view
				var target_layer = $('edit-widget-'+args.target_layer+'-'+args.instance_id);
				var vb = Position.getViewPortBounds();
				var pos = Position.cumulativeOffset(target_layer);
				var dim = Element.getDimensions(target_layer);

				if (pos[1] - 5 < vb.top || dim.height > vb.height) {
					new Effect.ScrollTo(target_layer, { offset: -5, duration: 0.5 });
				}
				else if (pos[1] + dim.height + 5 > vb.top + vb.height) {
					new Effect.ScrollTo(target_layer, { offset: -(vb.height - (dim.height + 5)), duration: 0.5 });
				}
			}
		}
	}
}

function confirmExit(args) {
	for (var i in widgetForms) {
		widgetForm = getWidgetForm(i);
		if (widgetForm.NumChanged) {
			return 'You have unsaved changes.';
		}
	}
	return;
}

var Overlay = {
	start:
	function(options) {
		this.options = options || {};
		if (UserAgent.MSIE)	{
			var	selects	= document.getElementsByTagName('select');
			for	(i = 0;	i <	selects.length;	i++) {
				selects[i].style.visibility	= 'hidden';
			}
		}
		if (!this.overlay) {
			this.refreshDisplayEL = this.refreshDisplay.bind(this);
			this.overlay = document.createElement('div');
			this.overlay.id = 'modal-background';
			this.overlay.className = 'modal-background';
			document.body.appendChild(this.overlay);
		}
		Element.setStyle(this.overlay, { visibility: 'hidden', width: '0', height: '0', display: '' });

		this.refreshDisplay();
		Element.setStyle(this.overlay, { visibility: '' });		

		Event.observe(window, 'resize', this.refreshDisplayEL);
		Event.observe(window, 'scroll', this.refreshDisplayEL);
	},
	
	stop:
	function() {
		Event.stopObserving(window, 'resize', this.refreshDisplayEL);
		Event.stopObserving(window, 'scroll', this.refreshDisplayEL);
		Element.hide(this.overlay);
		if (UserAgent.MSIE)	{
			var	selects	= document.getElementsByTagName('select');
			for	(i = 0;	i <	selects.length;	i++) {
				selects[i].style.visibility	= '';
			}
		}
	},

	refreshDisplay:
	function() {
		var	vB = Position.getViewPortBounds();
		Element.setStyle(this.overlay, { width: (vB.left + vB.width) + 'px', height: (vB.top + vB.height) + 'px' });
		if (this.options.dialog) {
			var left = (vB.left + ((vB.width - this.options.dialog.offsetWidth) / 2));
			var top = (vB.top + ((vB.height - this.options.dialog.offsetHeight) / 2));
			if (left < 0) left = 0;
			if (top < 0) top = 0;
			Element.setStyle(this.options.dialog, { left:  left + 'px', top: top + 'px' });
		}
	}
};
