function SimChair(container) {
	// 追加可能な家具の数
	this.number_of_chairs = 6;
	// コントロールパネルに縦に並ぶ数
	this.number_of_items = 3;

	this.rooms = [];
	this.chairs = [];
	this.cchairs = [];
	this.pitems = [];
	this.effects = {};
	this.hints = {};
	this.container = container;

	this.roomOffset = 0;
	this.panelOffset = 0;

	this._chairs = container.select('.chairs')[0];
	this._desks = container.select('.desks')[0];
	this._sofas = container.select('.sofas')[0];

	this._mask = container.select('.object_list_item_mask2')[0];
	this._mask3 = container.select('.object_list_item_mask3')[0];

	this._canvas_room = container.select('.canvas_room')[0];
	this._canvas_chair = container.select('.canvas_chair')[0];

	this._rooms = container.select('.rooms')[0];
	this._current_room = container.select('.current_room')[0];
	this._room_cursor = container.select('.room_cursor')[0];
	this._room_images = container.select('.room_images')[0];

	this._control_panel = container.select('.control_panel')[0];
	this._control_panel_item = container.select('.control_panel_item')[0];
	this._control_panel_item_active = null;

	this._upload_room = container.select('.upload_room')[0];

	this.current_cursor_room = null;
	this.current_room = null;
	this.current_panel = null;
	this.current_object_list = null;

	this.room_image_width = null;

	// constants
	this.cp_offset = 9;

	this._rooms.observe('mouseout', function() {
		var room = this.current_room;
		if (room && room.onSmallRoomMouseOver) {
			room.onSmallRoomMouseOver();
		}
	}.bind(this));

	Droppables.add(this._canvas_chair, {
		onDrop: function(elm) {
			if (elm.in_canvas || this.canvasCanAddChair(elm)) {
				this.ignoreHint('chairs');
				elm.draggable.options.revert = false;
				elm.draggable.options.ghosting = false;
				setTimeout(function() {
					elm.draggable.options.revert = true;
				}, 300);
				setTimeout(function() {
					this.canvasAddChair(elm);
				}.bind(this), 0);
			}
		}.bind(this)
	});

	this._chairs.observe('mouseover', function() {
		this.showHint('chairs');
	}.bind(this));
	this._chairs.observe('mouseout', function() {
		this.hideHint('chairs');
	}.bind(this));

	this._rooms.observe('mouseover', function() {
		this.showHint('rooms');
	}.bind(this));
	this._rooms.observe('mouseout', function() {
		this.hideHint('rooms');
	}.bind(this));

	this._upload_room.observe('mouseover', function() {
		this.showHint('upload_room');
	}.bind(this));
	this._upload_room.observe('mouseout', function() {
		this.hideHint('upload_room');
	}.bind(this));
}

SimChair.prototype = {
	addRoom: function(room) {
		var self = this;

		room.index = this.rooms.length;
		this.rooms.push(room);
		this.current_room = this.current_room || room;

		var sdiv = new Element('div');
		room.sdiv = sdiv;
		var ldiv = new Element('div');
		sdiv.addClassName('room_image');

		this._room_images.appendChild(sdiv);
		this._canvas_room.appendChild(ldiv);

		var sdiv_dim = null;
		var SdivClicked = function () {
			if (! sdiv_dim) {
				sdiv_dim = sdiv.getDimensions();
			}
			if (this.current_room) {
				this.current_room.sdiv.style.cursor = '';
			}
			this.current_room = room;
			this.current_room.sdiv.style.cursor = 'auto';

			if (this.effects._current_room) {
				this.effects._current_room.cancel();
			}
			if (this.effects._canvas_room) {
				this.effects._canvas_room.cancel();
			}


			this.effects._current_room = new Effect.Move(
				this._current_room,
				{
					x: (room.index - this.roomOffset) * sdiv_dim.width,
					y: 0,
					mode: 'absolute',
					duration: 0.3,
					fps: 60,
					delay: 0,
					afterFinishInternal: function(effect) {
						this.effects._current_room = null;
					}.bind(this)
				}
			);

			this.effects._canvas_room = new Effect.Move(
				this._canvas_room,
				{
					x: room.index * -limg.width,
					y: 0,
					mode: 'absolute',
					duration: 0.3,
					fps: 60,
					delay: 0,
					afterFinishInternal: function(effect) {
						this.effects._canvas_room = null;
					}.bind(this)
				}
			);
		}.bind(this);
		sdiv.observe('click', SdivClicked);

		room.onSmallRoomMouseOver = function() {
			if (this.current_cursor_room === room) {
				return;
			}
			this.current_cursor_room = room;

			if (this.effects._room_cursor) {
				this.effects._room_cursor.cancel();
			}

			this.effects._room_cursor = new Effect.Move(
				this._room_cursor,
				{
					x: (room.index - this.roomOffset) * this.getRoomImageWidth(),
					y: 0,
					mode: 'absolute',
					duration: 0.3,
					fps: 60,
					delay: 0,
					afterFinishInternal: function(effect) {
						this.effects._room_cursor = null;
					}.bind(this)
				}
			);
		}.bind(this);
		sdiv.observe('mouseover', room.onSmallRoomMouseOver);

		var simg_callbacks = {};
		if (this.rooms.length > 4) {
			simg_callbacks.load = function() {
				if (! sdiv_dim) {
					sdiv_dim = sdiv.getDimensions();
				}
				var move_x = - (this.rooms.length - this.roomOffset - 3) * sdiv_dim.width;
				this.roomOffset = this.rooms.length - 3;
				new Effect.Move(
					this._room_images,
					{
						x: move_x,
						y: 0,
						mode: 'relative',
						duration: 0.3,
						fps: 60,
						delay: 0
					}
				);

				room.onSmallRoomMouseOver();
				this.updateRoomsControl();

				SdivClicked();
			}.bind(this);
		}

		var limg = room.loadImage(ldiv, 'large');
		var simg = room.loadImage(sdiv, 'small', simg_callbacks);
	},
	addChair: function(chair) {
		var self = this;
		var _chairs = this['_' + chair.obj_type + 's'];

		if (chair.index === undefined) {
			chair.index = this.chairs.length;
			this.chairs.push(chair);
			this.current_chair = this.current_chair || chair;

			var div = new Element('div');
			div.style.position = 'relative';
			div.id = 'container_' + chair.obj_type + chair.index;
			div.addClassName('object_list_item_' + (_chairs.nitems % this.number_of_items));

			if (! _chairs.nitems) {
				_chairs.nitems = 0;
				_chairs.offset = 0;
				_chairs.mask = new Element('div');
				_chairs.mask.addClassName('object_list_item_mask2');
				_chairs.appendChild(_chairs.mask);
				_chairs.pages = new Array();
			}
			_chairs.nitems++;


			var page_number = Math.ceil(
				_chairs.nitems / this.number_of_items
			) - 1;
			if (! _chairs.pages[page_number]) {
				_chairs.pages[page_number] = new Element('div');
				_chairs.pages[page_number].style.position = 'absolute';
				_chairs.pages[page_number].style.zIndex = 5;
				_chairs.appendChild(_chairs.pages[page_number]);
			}
			_chairs.pages[page_number].appendChild(div);
		}
		else {
			var div = $('container_' + chair.obj_type + chair.index);
		}

		var img = chair.loadImage(div, 'right');
		img.style.position = 'absolute';
		img.style.cursor = 'move';
		img.style.zIndex = 100;
		img.chair = chair;
		img.draggable = chair.draggable = new Draggable(img, {
			ghosting: true,
			scroll: window,
			revert: true,
			onStart: function(elm) {
				if (
					(/*@cc_on!@*/false)
					&& (typeof document.documentElement.style.msInterpolationMode == "undefined")
				) {
					IEPNGFIX.fix(img);
				}
				if (img.panel) {
					self.activatePanelItem(img.panel);
				}
			},
			endeffect: function(element) { ; },
			placement: null
		});
		img.observe('mousedown', function() {
			if (img.panel) {
				self.activatePanelItem(img.panel);
			}
		});
	},
	canvasCanAddChair: function(chair_img) {
		if (chair_img.in_canvas) {
			return false;
		}
		if (this.cchairs.length >= this.number_of_chairs) {
			return false;
		}
		return true;
	},
	canvasAddChair: function(chair_img) {
		var self = this;

		if (chair_img.in_canvas) {
			return false;
		}
		if (this.cchairs.length >= this.number_of_chairs) {
			return false;
		}

		chair_img.in_canvas = true;
		chair_img.index = this.cchairs.length;
		this.cchairs.push(chair_img);
		this.current_chair = this.current_chair || chair_img.chair;

		this.addChair(chair_img.chair);

		this.addPanelItem(chair_img);

		return true;
	},
	updatePanelControl: function() {
		var prev = $$('.control_panel_prev')[0];
		var next = $$('.control_panel_next')[0];
		if (this.panelOffset > 0) {
			prev.removeClassName('control_prev_disable');
			prev.addClassName('control_prev_enable');
		}
		else {
			prev.removeClassName('control_prev_enable');
			prev.addClassName('control_prev_disable');
		}

		if (this.cchairs.length > this.panelOffset + 3) {
			next.removeClassName('control_next_disable');
			next.addClassName('control_next_enable');
		}
		else {
			next.removeClassName('control_next_enable');
			next.addClassName('control_next_disable');
		}

		if (! prev.actionInitialized) {
			var self = this;
			prev.observe('click', function() {
				if (prev.className.match(/disable/)) {
					return;
				}
				self.panelOffset--;
				self.slidePanel();
			});
			next.observe('click', function() {
				if (next.className.match(/disable/)) {
					return;
				}
				self.panelOffset++;
				self.slidePanel();
			});
		}
		prev.actionInitialized = true;
	},
	slidePanel: function(panel) {
		var self = this;
		var cp = $$('.control_panel')[0];
		if (! panel) {
			items = $$('.control_panel_item');
			panel = items[items.length - 1];
		}
		var dim = panel.getDimensions();

		new Effect.Move(cp, {
			x: 0,
			y: - self.panelOffset * (dim.height + self.cp_offset - 4),
			mode: 'absolute',
			duration: 0.3,
			fps: 60,
			delay: 0
		});
		this.updatePanelControl();
	},
	showPanel: function(panel) {
		if (
			(panel.index >= this.panelOffset)
			&& (panel.index < (this.panelOffset + 3))
		) {
			return;
		}
		else if (panel.index < this.panelOffset) {
			this.panelOffset = panel.index;
		}
		else {
			this.panelOffset = panel.index - 2;
		}

		this.slidePanel(panel);
	},
	activatePanelItem: function(panel) {
		if (this._control_panel_item_active == panel) {
			return;
		}

		if (this._control_panel_item_active) {
			this._control_panel_item_active.removeClassName(
				'control_panel_item_active'
			);
		}
		this._control_panel_item_active = panel;
		panel.addClassName('control_panel_item_active');

		this.showPanel(panel);
	},
	addPanelItem: function(chair_img) {
		var self = this;

		this.updatePanelControl();

		var panel = this._control_panel_item.cloneNode(true);
		this._control_panel.appendChild(panel);

		var dim = panel.getDimensions();

		panel.index = chair_img.index;
		this.pitems.push(panel);
		chair_img.panel = panel;

		panel.style.top = (panel.index * (dim.height + self.cp_offset)) + 'px';
		panel.style.left = dim.width + 'px';
		panel.style.display = '';

		if (panel.select('.chair_title')[0]) {
			panel.select('.chair_title')[0].innerHTML = chair_img.chair.name;
		}

		var chair_image = panel.select('.chair_image')[0];
		if (! chair_image.complete) {
			chair_image.style.display = 'none';
		}
		chair_image.onload = function() {
			var panel_in = panel.select('.chair_image_container')[0];
			var img = chair_image;

			if (window.opera) {
				var img_get_dim = img.getDimensions();
				img.width = img_get_dim.width;
				img.height = img_get_dim.height;
			}

			if (/*@cc_on!@*/false) {
				var img_get_dim = img.getDimensions();
				img.width = img_get_dim.width;
				img.height = img_get_dim.height;
				chair_image.onload = function() { ; };
			}

			var panel_dim = panel_in.getDimensions();
			var panel_ratio = panel_dim.width / panel_dim.height;
			var img_ratio = img.width / img.height;

			if (img_ratio > panel_ratio) {
				img.style.marginTop = Math.round(
					(panel_dim.height - img.height * panel_dim.width / img.width) / 2
				) + 'px';
				img.width = panel_dim.width;
			}
			else {
				img.style.marginLeft = Math.round(
					(panel_dim.width - img.width * panel_dim.height / img.height) / 2
				) + 'px';
				img.height = panel_dim.height;
			}

			img.style.display = '';
			if (
				(/*@cc_on!@*/false)
				|| (window.opera)
			) {
				if (img_ratio > panel_ratio) {
					img.height = panel_dim.width / img_ratio;
				}
				else {
					img.width = panel_dim.height * img_ratio;
				}
			}

			if (
				(/*@cc_on!@*/false)
				&& (typeof document.documentElement.style.msInterpolationMode == "undefined")
			) {
				IEPNGFIX.fix(img);
			}
		};
		chair_image.src = chair_img.chair_src;

		var slider = panel.select('.chair_size_slider')[0];
		new Control.Slider(slider.down('.slider_handle'), slider, {
			range: $R(70, 350),
			sliderValue: chair_img.width,
			onSlide: function(value) {
				chair_img.width = Math.round(value);
				chair_img.height = Math.round(value / chair_img.aspect_ratio);
				this.activatePanelItem(panel);
			}.bind(this),
			onChange: function(value) {
				chair_img.width = Math.round(value);
				chair_img.height = Math.round(value / chair_img.aspect_ratio);
				this.activatePanelItem(panel);
			}.bind(this)
		});
		this.activatePanelItem(panel);

		var dsel = panel.select('.chair_direction_selected')[0];
		var dsel_right = panel.select('.chair_direction_right')[0].positionedOffset().left;

		function updateDSel(type, direct) {
			if (type == 'left') {
				var x = 0;
			}
			else {
				var x = dsel_right;
			}

			if (direct) {
				dsel.style.left = x + 'px';
			}
			else {
				new Effect.Move(dsel, {
					x: x,
					y: 0,
					mode: 'absolute',
					duration: 0.3,
					fps: 60,
					delay: 0
				});
			}
		}

		var dirs = {};
		['left', 'right'].each(function(type) {
			var elm = panel.select('.chair_direction_' + type)[0];
			dirs[type] = elm;
			elm.observe('click', function() {
				chair_img.chair.setImage(chair_img, type);
				elm.style.cursor = 'auto';
				if (type == 'left') {
					dirs['right'].style.cursor = '';
				}
				else {
					dirs['left'].style.cursor = '';
				}

				updateDSel(type);

				self.activatePanelItem(panel);
			});
		});
		updateDSel(chair_img.direction);

		panel.select('.chair_delete')[0].observe('click', function() {
			if (
				(/*@cc_on!@*/false)
				&& (typeof document.documentElement.style.msInterpolationMode == "undefined")
			) {
				/* IE6 */
				chair_img.remove();
			}
			else {
				Effect.Fade(
					chair_img, {
						afterFinish: function() {
							chair_img.remove();
						}
					}
				);
			}

			var next_active = null;
			if (
				(self._control_panel_item_active != panel)
				|| (panel.index == 0)
			){
				next_active = -1;
			}
			else if (panel.index == (self.pitems.length - 1)) {
				next_active = panel.index - 1;
			}
			else {
				next_active = panel.index;
			}

			new Effect.Move(panel, {
				/*
				 * relative version
				x: dim.width,
				y: 0,
				mode: 'relative',
				*/
				x: dim.width,
				y: (panel.index * (dim.height + self.cp_offset)),
				mode: 'absolute',
				duration: 0.3,
				fps: 60,
				delay: 0,
				afterFinish: function() {
					self.pitems.splice(panel.index, 1);
					self.cchairs.splice(panel.index, 1);
					panel.remove();

					self.pitems.each(function(elm, index) {
						elm.index = index;
						new Effect.Move(elm, {
							x: 0,
							y: (index * (dim.height + self.cp_offset)),
							mode: 'absolute',
							duration: 0.3,
							fps: 60,
							delay: 0
						});

						if (next_active == index) {
							self.activatePanelItem(elm);
						}
					});

					self.cchairs.each(function(elm, index) {
						elm.index = index;
					});

					self.updatePanelControl();
				}
			});
		});

		new Effect.Move(panel, {
			/*
			 * relative version
			x: -dim.width,
			y: 0,
			mode: 'relative',
			*/
			x: 0,
			y: (panel.index * (dim.height + self.cp_offset)),
			mode: 'absolute',
			duration: 0.3,
			fps: 60,
			delay: 0
		});
	},
	showHint: function(type) {
		return;
		if (! this.hints[type]) {
			this.hints[type] = $$('.hint_' + type)[0];
		}
		var hint = this.hints[type];

		if (hint.ignore) {
			return;
		}

		if (this.effects['hint_' + type]) {
			this.effects['hint_' + type].cancel();
		}

		hint.style.zIndex = 100;
		this.effects['hint_' + type] = new Effect.Opacity(hint, {
    		from: hint.getOpacity() || 0.0,
    		to:   1.0,
			duration: 0.3
		});
	},
	hideHint: function(type, force) {
		return;
		if (! this.hints[type]) {
			this.hints[type] = $$('.hint_' + type)[0];
		}
		var hint = this.hints[type];

		if ((! force) && hint.ignore) {
			return;
		}

		if (this.effects['hint_' + type]) {
			this.effects['hint_' + type].cancel();
		}

		this.effects['hint_' + type] = new Effect.Opacity(hint, {
    		from: hint.getOpacity() || 1.0,
    		to:   0.0,
			duration: 0.3,
			afterFinish: function() {
				hint.style.zIndex = -1;
			}
		});
	},
	ignoreHint: function(type) {
		return;
		if (! this.hints[type]) {
			this.hints[type] = $$('.hint_' + type)[0];
		}
		var hint = this.hints[type];

		if (hint.ignore) {
			return;
		}
		hint.ignore = true;
		this.hideHint(type, true);
	},
	updateRoomsControl: function() {
		var prev = $$('.rooms_prev')[0];
		var next = $$('.rooms_next')[0];
		if (this.roomOffset > 0) {
			prev.removeClassName('prev_disable');
			prev.addClassName('prev_enable');
		}
		else {
			prev.removeClassName('prev_enable');
			prev.addClassName('prev_disable');
		}

		if (this.rooms.length > this.roomOffset + 3) {
			next.removeClassName('next_disable');
			next.addClassName('next_enable');
		}
		else {
			next.removeClassName('next_enable');
			next.addClassName('next_disable');
		}
	},
	getRoomImageWidth: function() {
		if (! this.room_image_width) {
			this.room_image_width = $$('.room_image')[0].getDimensions().width;
		}
		return this.room_image_width;
	},
	initRoomsControl: function() {
		var self = this;
		var prev = $$('.rooms_prev')[0];
		var next = $$('.rooms_next')[0];

		var onPrev = function() {
			if (this.roomOffset <= 0) {
				return;
			}
			if (this.moving && this.moving.length > 1) {
				setTimeout(onPrev, 100);
				return;
			}
			this.moving = [1,2,3];
			[this._current_room, this._room_cursor, this._room_images].each(
				function(elm) {
					new Effect.Move(
						elm,
						{
							x: self.getRoomImageWidth(),
							y: 0,
							mode: 'relative',
							duration: 0.3,
							fps: 60,
							delay: 0,
							afterFinish: function() {
								self.moving.shift();
							}
						}
					);
				}
			);

			this.roomOffset--;
			this.updateRoomsControl();
		}.bind(this);
		prev.observe('click', onPrev);

		var onNext = function() {
			if (this.rooms.length <= this.roomOffset + 3) {
				return;
			}
			if (this.moving && this.moving.length > 1) {
				setTimeout(onNext, 100);
				return;
			}
			this.moving = [1,2,3];
			[this._current_room, this._room_cursor, this._room_images].each(
				function(elm) {
					new Effect.Move(
						elm,
						{
							x: - self.getRoomImageWidth(),
							y: 0,
							mode: 'relative',
							duration: 0.3,
							fps: 60,
							delay: 0,
							afterFinish: function() {
								self.moving.shift();
							}
						}
					);
				});
			this.roomOffset++;
			this.updateRoomsControl();
		}.bind(this);
		next.observe('click', onNext);
	},
	updateObjectListControl: function() {
		var div = this.current_object_list;
		var prev = $$('.object_list_prev')[0];
		var next = $$('.object_list_next')[0];
		if (div.offset > 0) {
			prev.removeClassName('prev_disable');
			prev.addClassName('prev_enable');
		}
		else {
			prev.removeClassName('prev_enable');
			prev.addClassName('prev_disable');
		}

		if (div.nitems > (div.offset + 1) * 3) {
			next.removeClassName('next_disable');
			next.addClassName('next_enable');
		}
		else {
			next.removeClassName('next_enable');
			next.addClassName('next_disable');
		}
	},
	openObjectList: function(type) {
		var self = this;
		var div = this['_' + type + 's'];

		function update() {
			div.style.zIndex = 4;
			div.mask.style.zIndex = 6;
			div.pages[0].style.zIndex = 7;

			self.current_object_list = div;

			self.updateObjectList();
			self.updateObjectListControl();
		}
		if (this.current_object_list) {
				this._mask.style.zIndex = 15;
				this._mask3.style.zIndex = 15;
				new Effect.maskClose(
					new Array(self._mask, self._mask3), {
						afterFinish: function() {
							self.current_object_list.style.zIndex = 2;
							self.current_object_list.mask.style.zIndex = 2;
							self.current_object_list.pages.each(function(elm) {
								elm.style.zIndex = 2;
							});

							update();

							new Effect.unmaskOpen(
								new Array(self._mask, self._mask3), {
									afterFinish: function() {
										self._mask.style.zIndex = 0;
										self._mask3.style.zIndex = 0;
									}
								}
							);
						}
					}
				);
		}
		else {
			this.initObjectListControl();
			update();
		}
	},
	updateObjectList: function() {
		var div = this.current_object_list;
		div.style.zIndex = 4;
		div.mask.style.zIndex = 6;
		div.pages.each(function(elm, i) {
			if (i == div.offset) {
				elm.style.zIndex = 7;
			}
			else {
				elm.style.zIndex = 5;
			}
		});
	},
	initObjectListControl: function() {
		var self = this;
		var prev = $$('.object_list_prev')[0];
		var next = $$('.object_list_next')[0];
		prev.observe('click', function() {
			var div = self.current_object_list;
			if (div.offset > 0) {
				div.offset--;
				self._mask.style.zIndex = 15;
				self._mask.style.right = '0px';
				self._mask.style.width = '0px';
				new Effect.maskRightToLeft(
					self._mask, {
						afterFinish: function() {
							self.updateObjectList();
							self.updateObjectListControl();
							new Effect.unmaskLeftToRight(self._mask, {
								afterFinish: function() {
									self._mask.style.zIndex = 0;
									self._mask.style.right = '';
								}
							});
						}
					}
				);
			}
		});
		next.observe('click', function() {
			var div = self.current_object_list;
			if (div.nitems > (div.offset + 1) * 3) {
				div.offset++;
				self._mask.style.zIndex = 15;
				self._mask.style.width = '0px';
				new Effect.maskLeftToRight(
					self._mask, {
						afterFinish: function() {
							self.updateObjectList();
							self.updateObjectListControl();
							new Effect.unmaskRightToLeft(self._mask, {
								afterFinish: function() {
									self._mask.style.zIndex = 0;
								}
							});
						}
					}
				);
			}
		});

		var object_type_selected = $$('.object_type_selected')[0];
		$$('.object_type_item').each(function(elm, i) {
			function move(after_func) {
				var off = elm.cumulativeOffset();
				new Effect.Move(object_type_selected, {
					x: off.left,
					y: off.top,
					mode: 'absolute',
					duration: 0.3,
					fps: 60,
					delay: 0,
					afterFinish: function() {
						if (after_func) {
							after_func();
						}
					}
				});
			}
			elm.observe('click', function() {
				var res = elm.id.match(/object_type_item_(.*)/);
				self.openObjectList(res[1]);
				move();
			});
			if (i == 0) {
				object_type_selected.style.visibility = 'hidden';

				if (false) {
					object_type_selected.style.visibility = 'hidden';
					move(function() {
						object_type_selected.style.visibility = 'visible';
					});
				}

				setTimeout(function() {
					var off = elm.cumulativeOffset();
					object_type_selected.style.top = off.top + 'px';
					object_type_selected.style.left = off.left + 'px';
					object_type_selected.style.visibility = 'visible';
				}, 500);
			}
		});
	},
	placement: null
}

function Room(hash) {
	for (k in hash) {
		this[k] = hash[k];
	}
}
Room.prototype = {
	loadImage: function(elm, type, callbacks) {
		var img = new Element('img');
		if (callbacks) {
			for (k in callbacks) {
				img.observe(k, callbacks[k]);
			}
		}
		elm.appendChild(img);
		img.src = this['link_' + type];
		return img;
	},
	placement: null
}

function Chair(hash) {
	for (k in hash) {
		this[k] = hash[k];
	}
	this.obj_type = 'chair';
}
Chair.prototype = {
	loadImage: function(elm, type) {
		var img = new Element('img');
		/*
		if (elm) {
			elm.appendChild(img);
		}
		*/
		this.setImage(img, type, elm);
		return img;
	},
	setImage: function(img, type, panel) {
		if (! type) {
			type = 'right';
		}

		if (! img.onload) {
			img.onload = function() {
				var panel_dim = panel.getDimensions();

				var panel_ratio = panel_dim.width / panel_dim.height;
				var img_ratio = img.width / img.height;
				img.aspect_ratio = img_ratio;
				if (img_ratio > panel_ratio) {
					img.height = img.height * panel_dim.width / img.width;
					img.style.marginTop = Math.round(
						(panel_dim.height - img.height) / 2
					) + 'px';
					img.width = panel_dim.width;
				}
				else {
					img.width = img.width * panel_dim.height / img.height;
					img.style.marginLeft = Math.round(
						(panel_dim.width - img.width) / 2
					) + 'px';
					img.height = panel_dim.height;
				}

				panel.appendChild(img);
				if (
					(/*@cc_on!@*/false)
					&& (typeof document.documentElement.style.msInterpolationMode == "undefined")
				) {
					IEPNGFIX.fix(img);
				}
			};
		}
		else {
			img.onload = function() {
				if (
					(/*@cc_on!@*/false)
					&& (typeof document.documentElement.style.msInterpolationMode == "undefined")
				) {
					IEPNGFIX.fix(img);
				}
			};
		}

		if (this['link_image_' + type]) {
			img.chair_src = img.src = this['link_image_' + type];
		}
		else {
			img.chair_src = img.src = this.obj_type + '/' + this.id_name + '_' + type + '.png';
		}
		img.size_initialized = true;
		img.direction = type;
		return img;
	},
	placement: null
}

function Desk() {
	Chair.apply(this, arguments);
	this.obj_type = 'desk';
}
Desk.prototype = new Chair;
Desk.prototype.constructor = Desk;

function Sofa() {
	Chair.apply(this, arguments);
	this.obj_type = 'sofa';
}
Sofa.prototype = new Chair;
Sofa.prototype.constructor = Sofa;

__object_list_width = null;
function getObjectListWidth() {
	if (! __object_list_width) {
		__object_list_width = $$('.object_list_item_mask')[0].getDimensions().width;
	}
	return __object_list_width;
}

Effect.maskLeftToRight = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);

		if (this.element.current_effect) {
			this.element.current_effect.cancel();
		}
		this.element.current_effect = this;

		this.prev = $$('.object_list_prev')[0];

	var options = Object.extend({
		from: 0,
		to: getObjectListWidth(),
		duration: 0.5
    }, arguments[1] || { });
    this.start(options);
  },
  update: function(width) {
		this.element.style.width = width + 'px';
		this.prev.style.left = width + 'px';
  }
});

Effect.unmaskRightToLeft = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);

		if (this.element.current_effect) {
			this.element.current_effect.cancel();
		}
		this.element.current_effect = this;

		this.prev = $$('.object_list_prev')[0];

    var options = Object.extend({
      from: getObjectListWidth(),
      to: 0,
			duration: 0.5
    }, arguments[1] || { });
    this.start(options);
  },
  update: function(width) {
		this.element.style.width = width + 'px';
		this.prev.style.left = width + 'px';
  }
});

Effect.maskRightToLeft = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);

		if (this.element.current_effect) {
			this.element.current_effect.cancel();
		}
		this.element.current_effect = this;

		this.next = $$('.object_list_next')[0];

    var options = Object.extend({
      from: 0,
      to: getObjectListWidth(),
			duration: 0.5
    }, arguments[1] || { });
    this.start(options);
  },
  update: function(width) {
		this.element.style.width = width + 'px';
		this.next.style.left = '-' + width + 'px';
  }
});

Effect.unmaskLeftToRight = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);

		if (this.element.current_effect) {
			this.element.current_effect.cancel();
		}
		this.element.current_effect = this;

		this.next = $$('.object_list_next')[0];

    var options = Object.extend({
      from: getObjectListWidth(),
      to: 0,
			duration: 0.5
    }, arguments[1] || { });
    this.start(options);
  },
  update: function(width) {
		this.element.style.width = width + 'px';
		this.next.style.left = '-' + width + 'px';
  }
});

Effect.maskClose = Class.create(Effect.Base, {
  initialize: function(element) {
		this.masks = element;
		this.masks[0].style.left = '0px';
		this.masks[1].style.right = '0px';

		if (this.masks[0].current_effect) {
			this.masks[0].current_effect.cancel();
		}
		this.masks[0].current_effect = this;

		this.next = $$('.object_list_next')[0];
		this.prev = $$('.object_list_prev')[0];

    var options = Object.extend({
      from: 0,
      to: getObjectListWidth(),
			duration: 0.5
    }, arguments[1] || { });
    this.start(options);
  },
  update: function(width) {
		var half = Math.round(width / 2);
		this.masks[0].style.width = half + 'px';
		this.masks[1].style.width = half + 'px';

		this.next.style.left = '-' + half + 'px';
		this.prev.style.left = half + 'px';
  }
});

Effect.unmaskOpen = Class.create(Effect.Base, {
  initialize: function(element) {
		this.masks = element;
		this.masks[0].style.left = '0px';
		this.masks[1].style.right = '0px';

		if (this.masks[0].current_effect) {
			this.masks[0].current_effect.cancel();
		}
		this.masks[0].current_effect = this;

		this.next = $$('.object_list_next')[0];
		this.prev = $$('.object_list_prev')[0];

    var options = Object.extend({
      from: getObjectListWidth(),
      to: 0,
			duration: 0.5
    }, arguments[1] || { });
    this.start(options);
  },
  update: function(width) {
		var half = Math.round(width / 2);
		this.masks[0].style.width = half + 'px';
		this.masks[1].style.width = half + 'px';
		this.next.style.left = '-' + half + 'px';
		this.prev.style.left = half + 'px';
  },
	finish: function() {
		this.masks[0].style.left = '';
		this.masks[1].style.right = '';
	}
});

document.observe('dom:loaded', function() {
	$$('.hint').each(function(elm) {
		elm.setOpacity(0.0);
		elm.style.zIndex = -1;
	});

	var uh = $('upload_hint');
	var octop = uh.cumulativeOffset().top + uh.getDimensions().height + 10;
	$$('.canvas_outer_container')[0].style.top = octop + 'px';
	$$('.contents')[0].style.height = (octop + 280) + 'px';
});
