// require prototype.js and php_func.js

var FormAssist = {
	load: function(forms, vars, options) {
		if (vars === undefined) {
			vars = {};
		}
		if (options === undefined) {
			options = {};
		}
		new Inputset(forms, vars, options);
	}
};

var Inputset = Class.create({
	initialize: function(form, vars, options) {
		this.inputs = {};
		var h_options = $H(options);
		var forms = $H(form);
		forms.each(function(pair) {
			var classname = window[pair.value.ucfirst()];
			this.inputs[pair.key] = (new classname(pair.key, h_options.get(pair.key)));
		}.bind(this));
		this.set(vars);
	},
	set: function(vars) {
		var h_vars = $H(vars);
		h_vars.each(function(pair) {
			if(this.inputs[pair.key] === undefined) {
				return;
			}
			this.inputs[pair.key].set(pair.value);
		}.bind(this));
	}
});

var InputElement = Class.create({
	initialize: function(name, options) {
		this.element = $(name);
		this.options = $H(options);
	},
	get: function() {
		return $F(this.element);
	},
	set: function(value) {
		this.element.value = value;
	}
});

var NotifiableElement = Class.create(InputElement, {
	initialize: function($super, name, options) {
		$super(name, options);
		this.observers = [];
		this.element.observe('change', this.onchange.bind(this));
	},
	setObserver: function(observer) {
		this.observers.push(observer);
	},
	onchange: function() {
		this.notify();
	},
	notify: function() {
		this.observers.each(function (observer) {
			observer.update(this.get())
		}.bind(this));
	},
	set: function($super, value) {
		$super(value);
		this.notify();
	}
});

var NotifiableSelect = Class.create(NotifiableElement, {
	replace: function(list) {
		var index = this.options.get('exclusive') !== undefined ? this.options.get('exclusive') : 0;
		$A($R(index, this.element.options.length)).reverse().each(function (i) {
			this.element.remove(i);
		}.bind(this));
		var i = index;
		list.each(function (item) {
			this.element.options[i++] = new Option(item.name, item.value);
		}.bind(this));
	},
	replaceFromAjax: function(transport) {
		var list = transport.responseText.evalJSON(true);
		this.replace(list);
	},
	set: function(value) {
		var found = $A(this.element.options).find(function (option) {
			return option.value == value;
		});
		if (found !== undefined) {
			found.selected = true;
		}
		this.notify();
	}
});

var Occupation = Class.create({
	initialize: function(name, options) {
		this.select = [];
		this.select[0] = new OccupationSelectFirst(name+'_0', options);
		this.select[1] = new OccupationSelectSecond(name+'_1', options);
		this.select[2] = new OccupationSelectThird(name+'_2', options);
		this.select[0].setObserver(this.select[1]);
		this.select[1].setObserver(this.select[2]);
	},
	get: function() {
		return $F(this.select[2]);
	},
	set: function(value) {
		if (typeof value == 'object') {
			$R(0,2).each(function (i) {
				this.select[i].set(value[i]);
			}.bind(this));
		} else {
			new Ajax.Request(
				"/ajax/occupation.php",
				{
					method: 'get',
					asynchronous: false,
					requestHeaders: {Accept: 'application/json'},
					parameters: "get=category&value="+value,
					onSuccess: this.setFromResponseText.bind(this)
				}
			);
		}
	},
	setFromResponseText: function(req) {
		this.set(req.responseText.evalJSON()).bind(this);
	}
});

var City = Class.create({
	initialize: function(name, options) {
		this.select = [];
		this.select[0] = new CitySelectFirst(name+'_0', options);
		this.select[1] = new CitySelectSecond(name+'_1', options);
		this.select[0].setObserver(this.select[1]);
	},
	get: function() {
		return $F(this.select[1]);
	},
	set: function(value) {
		$R(0,1).each(function (i) {
			this.select[i].set(value[i]);
		}.bind(this));
	}
});

var Station = Class.create({
	initialize: function(name, options) {
		this.select = [];
		this.select[0] = new StationSelectFirst(name+'_0', options);
		this.select[1] = new StationSelectSecond(name+'_1', options);
		this.select[2] = new StationSelectThird(name+'_2', options);
		this.select[3] = new StationSelectFourth(name+'_3', options);
		this.select[0].setObserver(this.select[1]);
		this.select[1].setObserver(this.select[3]);
		this.select[1].setObserver(this.select[2]);
		this.select[2].setObserver(this.select[3]);
	},
	get: function() {
		return $F(this.select[1]);
	},
	set: function(value) {
		$R(0,3).each(function (i) {
			this.select[i].set(value[i]);
		}.bind(this));
	}
});

var Feature = Class.create({
	initialize: function(name, options) {
		this.feature = [];
		this.feature[0] = new NotifiableSelect(name+'_0', options);
		this.feature[1] = new NotifiableSelect(name+'_1', options);
	},
	get: function() {
		return this.feature[0].get();
	},
	set: function(value) {
		this.feature[0].set(value[0]);
		this.feature[1].set(value[1]);
	}
});

var Salary   = Class.create(NotifiableSelect, {});
var Age      = Class.create(NotifiableSelect, {});
var Color    = Class.create(NotifiableSelect, {});
var Industry = Class.create(NotifiableSelect, {});

var Freeword = Class.create(InputElement, {});
var Inexperienced = Class.create(InputElement, {
	get: function() {
		return this.element.checked;
	},
	set: function(value) {
		if (value) {
			this.element.checked = true;
		} else {
			this.element.checked = false;
		}
	}
});

var Employment = Class.create({
	initialize: function(name, options) {
		this.employment = [];
		this.employment['permanent'] = new InputElement(name+'_0', options);
		this.employment['temporary'] = new InputElement(name+'_1', options);
		this.employment['other']     = new InputElement(name+'_2', options);
	},
	get: function() {
		return 1;
	},
	set: function(value) {
		$A(value).each(function(name) {
			if (this.employment[name] !== undefined) {
				this.employment[name].element.checked = true;
			}
		}.bind(this));
	}
});

var OccupationSelectFirst = Class.create(NotifiableSelect, {
	initialize: function($super, name, options) {
		$super(name, options);
		new Ajax.Request(
			"/ajax/occupation.php",
			{
				method: 'get',
				asynchronous: false,
				requestHeaders: {Accept: 'application/json'},
				parameters: "get=first",
				onSuccess: this.replaceFromAjax.bind(this)
			}
		);
	}
});
var OccupationSelectSecond = Class.create(NotifiableSelect, {
	update: function(value) {
		if (value == 0) {
			this.replace([]);
		} else {
			new Ajax.Request(
				"/ajax/occupation.php",
				{
					method: 'get',
					asynchronous: false,
					requestHeaders: {Accept: 'application/json'},
					parameters: "get=second&value="+value,
					onSuccess: this.replaceFromAjax.bind(this)
				}
			);
		}
		this.notify();
	}
});
var OccupationSelectThird = Class.create(NotifiableSelect, {
	update: function(value) {
		if (value == 0) {
			this.replace([]);
		} else {
			new Ajax.Request(
				"/ajax/occupation.php",
				{
					method: 'get',
					asynchronous: false,
					requestHeaders: {Accept: 'application/json'},
					parameters: "get=third&value="+value,
					onSuccess: this.replaceFromAjax.bind(this)
				}
			);
		}
		this.notify();
	}
});
var CitySelectFirst = Class.create(NotifiableSelect, {
	initialize: function($super, name, options) {
		$super(name, options);
		new Ajax.Request(
			"/ajax/city.php",
			{
				method: 'get',
				asynchronous: false,
				requestHeaders: {Accept: 'application/json'},
				parameters: "get=first&value="+this.options.get('area'),
				onSuccess: this.replaceFromAjax.bind(this)
			}
		);
	}
});
var CitySelectSecond = Class.create(NotifiableSelect, {
	update: function(value) {
		if (value == 0) {
			this.replace([]);
		} else {
			new Ajax.Request(
				"/ajax/city.php",
				{
					method: 'get',
					asynchronous: false,
					requestHeaders: {Accept: 'application/json'},
					parameters: "get=second&value="+value,
					onSuccess: this.replaceFromAjax.bind(this)
				}
			);
		}
		this.notify();
	}
});
var StationSelectFirst = Class.create(NotifiableSelect, {
	initialize: function($super, name, options) {
		$super(name, options);
		new Ajax.Request(
			"/ajax/station.php",
			{
				method: 'get',
				asynchronous: false,
				requestHeaders: {Accept: 'application/json'},
				parameters: "get=corporation&area="+this.options.get('area'),
				onSuccess: this.replaceFromAjax.bind(this)
			}
		);
	}
});
var StationSelectSecond = Class.create(NotifiableSelect, {
	initialize: function($super, name, options) {
		$super(name, options);
		this.options.set('exclusive', 0);
	},
	update: function(value) {
		if (value == 0) {
			this.replace([{"name": "▼選択してください", "value": 0}]);
		} else {
			new Ajax.Request(
				"/ajax/station.php",
				{
					method: 'get',
					asynchronous: false,
					requestHeaders: {Accept: 'application/json'},
					parameters: "get=line&value="+value+"&area="+this.options.get('area'),
					onSuccess: this.replaceFromAjax.bind(this)
				}
			);
		}
		this.notify();
	}
});
var StationSelect = Class.create(NotifiableSelect, {
	addAll: function() {
		$A($R(0, this.element.options.length-1)).reverse().each(function (index) {
			var option = this.element.options[index];
			this.element.options[index+1] = new Option(option.innerHTML, option.value);
		}.bind(this));
		this.element.options[0] = new Option("--全て--", 'all');
		this.element.options[0].selected = true;
	}
});
var StationSelectThird = Class.create(StationSelect, {
	initialize: function($super, name, options) {
		$super(name, options);
		this.options.set('exclusive', 0);
	},
	update: function(value) {
		if (value == 0) {
			this.replace([{"name": "▼選択してください", "value": 0}]);
		} else {
			new Ajax.Request(
				"/ajax/station.php",
				{
					method: 'get',
					asynchronous: false,
					requestHeaders: {Accept: 'application/json'},
					parameters: "get=station&value="+value,
					onSuccess: this.replaceFromAjax.bind(this)
				}
			);
			this.addAll();
		}
		this.notify();
	},
	notify: function() {
		this.observers.each(function (observer) {
			observer.update2(this.get())
		}.bind(this));
	}
});
var StationSelectFourth = Class.create(StationSelect, {
	initialize: function($super, name, options) {
		$super(name, options);
		this.options.set('exclusive', 0);
	},
	update: function(value) {
		if (value == 0) {
			this.replace([{"name": "▼選択してください", "value": 0}]);
		} else {
			new Ajax.Request(
				"/ajax/station.php",
				{
					method: 'get',
					asynchronous: false,
					requestHeaders: {Accept: 'application/json'},
					parameters: "get=station&value="+value,
					onSuccess: this.replaceFromAjax.bind(this)
				}
			);
		}
		this.notify();
	},
	update2: function(value) {
		if (value == 0) {
			this.replace([{"name": "▼選択してください", "value": 0}]);
			this.element.disabled = false;
		} else if (value == 'all') {
			this.addAll();
			this.element.disabled = true;
		} else {
			if (this.element.options[0].value == 'all') {
				this.element.removeChild(this.element.options[0]);
			}
			$A(this.element.options).find(function(option) {
				return option.value == value;
			}).selected = true;
			this.element.disabled = false;
		}
	}
});
