

var Door = Class.create({
	initialize: function() {
		this.path = false;
	},
	attach: function(frame) {
		frame.door = this;
		this.frame = frame;
		this.path = frame.getAttribute('path');
		this.drag = frame.getAttribute('drag');
		this.drop = frame.getAttribute('drop');
		this.version = frame.getAttribute('version');

		if(!Door.map[this.path]) { Door.map[this.path] = [ ]; }
		Door.map[this.path].push(this);

		this.seekOuter();

		return this;
	},
	detach: function() {
		this.frame.door = false;
		this.frame = false;
		if(this.that) { this.that.detach(); }
		if(this.other) { this.other.detach(); }

		return this;
	},
	link: function(outer) {
		this.outer = outer;

		return this;
	},
	unlink: function() {
		this.outer = false;
		if(this.that) { this.that.unlink(); this.that = false; }
		if(this.other) { this.other.unlink(); this.other = false; }

		return this;
	},
	seekOuter: function() {
		if(this.frame)
		{
			var outer = Door.frame(this.frame);
			if(outer)
			{
				this.link(outer);
			}
		}
	},
	clear: function() {
		this.frame.innerHTML = '';

		return this;
	},
	load: function(path, actions) {
		var door = this;

		new Effect.Opacity(door.frame, { from:1, to:0.5, duration:0.25});

		new Ajax.Request('ajax.php', {
			parameters: $H({
				path: path,
				version: this.version
			}).merge(actions),
			onComplete: function(t) {
				new Effect.Opacity(door.frame, { from:0.5, to:1, duration:0.25});
				door.frame.update(t.responseText);
				Door.decorate();
			}
		});

		return this;
	},
	fetch: function(actions, dsts) {
		var door = this;

		dsts.each(function(door) {
			new Effect.Opacity(door.frame, { from:1, to:0.5, duration:0.25});
		});

		new Ajax.Request('ajax.php', {
				parameters: $H({
					path: this.path,
					version: this.version
				}).merge(actions),
				onComplete: function(t) {
					dsts.each(function(door) {
						new Effect.Opacity(door.frame, { from:0.5, to:1, duration:0.25});
						door.frame.update(t.responseText);
						Door.decorate();
					});
				}
			}
		);

		return this;
	},
	relabel: function(label, id) {
		this.fetch(
			{ 'store-label': $H({ id: id, version: this.version, label: encodeURIComponent(label).gsub('!', '%21') }).toQueryString() },
			Door.map[this.path]
		);

		return this;
	},
	set: function(scene) {
		var drop = this.drop.split('/');
		var data = { 'set-member': $H({ id: drop[0], version: this.version, member: drop[1], scene: scene }).toQueryString() };
		if(!this.outer)
		{
			Door.map[this.path] = Door.map[this.path].without(this);
			this.path = 'manager/scene/'+scene;
			this.drag = ''+scene;

			if(!Door.map[this.path]) { Door.map[this.path] = [ ]; }
			Door.map[this.path].push(this);

			this.fetch(data, [ this ]);
		}
		else
		{
			this.outer.fetch(data, Door.map[this.outer.path]);
		}

		return this;
	},
	setMember: function(id, member, scene) {
		this.fetch(
			{ 'set-member': $H({ id: id, version: this.version, member: member, scene: scene }).toQueryString() },
			Door.map[this.path]
		);

		return this;
	},
	watch: function(el, id) {
		var unwatch = function(event, el) {
			el.stopObserving('blur', unwatch);
			el.stopObserving('keypress', modified);
			el.observe('focus', function(event, el) {
				this.watch(el);
			}.bindAsEventListener(this, el));
		}.bindAsEventListener(this, el);
		var modified = function(event, el) {
			Door.map[this.path].each(function(door) {
				door.frame.setStyle({ border: '1px dotted #000' });
			});
			this.frame.setStyle({ border: '1px dashed #000' });
			el.stopObserving('keypress', modified);
			el.stopObserving('blur', unwatch);
			el.observe('blur', store);
		}.bindAsEventListener(this, el);
		var store = function(event, el) {
			Door.map[this.path].each(function(door) {
				door.frame.setStyle({ border: 'none' });
			});
			el.stopObserving('blur', store);
			this.relabel(el.value, id);
		}.bindAsEventListener(this, el);

		el.observe('keypress', modified);
		el.observe('blur', unwatch);

		return this;
	},
	toggleContent: function() {
		var content = this.frame.down('.scene-content');
		if(content != undefined)
		{
			content.toggle();
		}
		else
		{
			this.fetch(
				{ },
				[ this ]
			);
		}
	}
});


Door.map = [ ];

Door.frame = function(el) {
	var frame = el.up('.door-frame');
	if(frame) { return frame.door; }
};

Door.decorate = function() {
	$$('.door-frame').each(function(frame) {
		if(!frame.door)
		{
			var door = new Door();
			door.attach(frame);

			Droppables.add(frame, {
				hoverclass: 'hover',
				onDrop: function(dragged, dropped, event) {
					var drop = dropped.door.drop.split('/');
					if(dropped.door.outer)
						dropped.door.outer.setMember(drop[0], drop[1], dragged.parentNode.door.drag);
				}
			});
		}
	});

	$$('.door-frame>*').each(function(frame) {
		if(Draggables.drags.include(frame.dragger))
		{
			Draggables.unregister(frame.dragger);
			Draggables.register(frame.dragger);
		}
		else
		{
			frame.dragger = new Draggable(frame, {
				revert: true,
				ghosting: true,
				handle: 'handle',
				dragelement: function(el, event) {
					var ghost = Builder.node(
						'div',
						{
							className: 'drag-ghost',
							style: 'position: absolute; width: 64px; height: 24px;'
						}
					);
					ghost.door = el.door;
					$(document.body).insert(ghost);
					return ghost;
				}
			});
		}
	});
};
registerFrameDecorator(Door.decorate);
