function TruckList(div) {
	this.div = div;
	this.trucks = new Object();
	this.biggest;
	this.currentTrucks = new Object;

	this.setBiggest = function() {
		var biggest = 0;
		for (var id in this.trucks)
			if (biggest == 0 || this.trucks[id].feet > biggest.feet)
				biggest = this.trucks[id];
		this.biggest = biggest;
	};
	
	this.addTruck = function(truck) {
		this.trucks[truck.id] = truck;
	};
	
	this.toString = function(prop) {
		var string = "";
		if (prop == 'id') for (var name in this.currentTrucks) string = string + '__' + this.currentTrucks[name].id;
		else if (prop == 'name') for (var name in this.currentTrucks) string = string + '__' + name;
		else for (var name in this.currentTrucks) string = string + '__' + this.currentTrucks[name].id + '__' + name + '__' + this.currentTrucks[name].num;
		return string;
	};
	
	this.getTruck = function(feet) {
		if (feet == 0) {
			$('truck-size').addClass('off-left');
			return;
		}
		$('truck-size').removeClass('off-left');
		for (var id in this.trucks) this.trucks[id].num = 0;
		while (feet > 0) 
			if (feet > this.biggest.feet) {
				this.trucks[this.biggest.id].num++;
				feet -= this.biggest.feet;
			}
			else { 
				var id = this.getClosest(feet);
				this.trucks[id].num++;	
				feet -= this.trucks[id].feet;
			}
		var string = "";
		var i = 0;
		this.currentTrucks = new Object();
		for (var id in this.trucks) {
			if (this.trucks[id].num >= 1) {
				this.currentTrucks[this.trucks[id].name] = new Object();
				this.currentTrucks[this.trucks[id].name].id = id;
				this.currentTrucks[this.trucks[id].name].name = this.trucks[id].name;
				this.currentTrucks[this.trucks[id].name].num = this.trucks[id].num;
			}
			if (this.trucks[id].num == 1) {
				if (i > 0) string += ' and ';
				string = string + this.trucks[id].modifier + '<a href="/trucks/display/' + id + '">' + this.trucks[id].name + '</a>';
				i++;
			}
			else if (this.trucks[id].num > 1) {
				if (i > 0) string += ' and ';
				string = string + this.trucks[id].num + ' <a href="/trucks/display/' + id + '">' + this.trucks[id].name + this.trucks[id].plural + '</a>';
				i++;
			}	
		}	
		$(this.div).innerHTML = string;
	};
	
	this.getClosest = function(feet) {
		var i = 0;
		var closest = null;
		for (var id in this.trucks) 
			if (this.trucks[id].feet > feet) {
				closest = id;
				break;
			}
		for (var id in this.trucks) 
			if (this.trucks[id].feet > feet && (this.trucks[id].feet - feet) < (this.trucks[closest].feet - feet)) {
				closest = id;
				i++;
			}
		return closest;
	};
}

function Truck(name,id,feet,length) {
	this.name = name;
	this.id = id;
	this.feet = feet;
	this.size = length;
	this.num = 0;
	this.setModifier = function() {
		var re = /^[aeiouAEIOU]/
		if (re.test(this.name)) return 'an ';
		return 'a ';
	}
	this.setPlural = function() {
		var re = /[(ch)(sh)]$/
		if (re.test(this.name)) return 'es';
		re = /y$/
		if (re.test(this.name)) return 'ies';
		return 's';
	}
	this.plural = this.setPlural();
	this.modifier = this.setModifier();
}

function Quote(entireHome,fadeFrom,fadeTo,minQuote,distance,costMile,storage,hourly,speed,range,drivingCost,fromMultiplier,toMultiplier,haveTruck,selfLoad,selfUnload,trucks) {
	this.hourly = hourly;
	this.speed = speed;
	this.range = range;
	this.drivingCost = drivingCost;
	this.selfLoad  = selfLoad;
	this.haveTruck = haveTruck;
	this.selfUnload  = selfUnload;
	this.trucks = trucks;
	this.fromMultiplier = fromMultiplier;
	this.toMultiplier = toMultiplier;
	this.skip = true;
	this.totalCost = 0;
	this.storeSize = 0;
	this.hasStorage = storage;
	this.distance = distance;
	this.costMile = costMile;
	this.fadeFrom = fadeFrom;
	this.fadeTo = fadeTo;
	this.minQuote = minQuote;
	this.timer;
	this.firstRun = true;
	this.entireHome = entireHome;
	this.queue = false;
	this.location = false;
	
	this.roomsToString = function() {		
		var string = '';
		var storage = '';
		var rooms = new Array();
		$('room-selection').getElements("div[class^='room-set']").each(function(div){
			var substring = '';
			var roomId = new StringTokenizer(div.id,'-',1).nextToken();
			var roomLabel = new StringTokenizer(div.id,'-',2).nextToken();
			var roomCustomLabel = div.getElement('h2').getElement('span').get('text').underscore();
			if (roomCustomLabel == 'your_storage_unit') roomCustomLabel = 'storage_unit';
			substring = substring + "@" + roomId + '@' + roomCustomLabel;
			var list = $(div.id).retrieve('room').list;
			substring = substring + '@' + list.length();			
			roomItems = new Array();
			list.getObjects().each(function(item){roomItems.push('@' + item.id + '@' + item.quantity)});
			roomItems.sort(this.itemSort).each(function(item){substring += item});
			if (div.id != 'move-0-storage_unit') rooms.push(substring);
			else storage = substring;
		},this);
		var sorted = rooms.sort(this.roomSort);
		if (storage != '') rooms.push(storage);
		sorted.each(function(room){string += room});
		new Request({url:'/quote/update/update_quote_data/' + requestString([this.totalCost,this.storeSize,add(this.moveWeight,this.storeWeight),this.hasStorage,string + '@']),onComplete:function(){
			this.queue = false;
			if (this.location) window.location = this.location;
		}.bind(this)}).send();
	};
	
	this.sendTo = function(location) {this.location = location}
	
	this.itemSort = function(a,b) {
		a = new StringTokenizer(a,'@').nextToken();
		b = new StringTokenizer(b,'@').nextToken();
		for (var id in this.itemList) {
			if (id == a) return false;
			if (id == b) return true;
		}
	};
	
	this.roomSort = function(a,b) {
		a = new StringTokenizer(a,'@').nextToken();
		b = new StringTokenizer(b,'@').nextToken();	
		for (var id in this.roomList) {
			if (id == a) return false;
			if (id == b) return true;
		}
	};
	
	this.setStorage = function(s) {this.hasStorage = s}
	
	this.calculate = function() {
		if (openDiv && $chk($(openDiv))) {
			var num = 0;
			$(openDiv).getElement('div[class=item-area]').getElements('input[id$=input]').each(function(inp){num += inp.value.toInt()});
			$(openDiv + '-num').set('html',num);
		}
		var boxMultiplier = 0.05; 
		var move = [0,0];
		var box = [0,0];
		var moveWeight = 0;
		var storeWeight = 0;
		$('room-selection').getElements("div[class^='room-set']").each(function(div){
			$(div.id).retrieve('room').list.getObjects().each(function(item){
				if (this.label != 'storage_unit') moveWeight += item.weight * item.quantity;
				else storeWeight += item.weight * item.quantity;
			},$(div.id).retrieve('room'));
		});
	//	this.trucks.getTruck(parseInt((moveWeight + storeWeight) / 7));	
		if (moveWeight + storeWeight == 0) allowContinue(false);
		else allowContinue(true);
		var fullLoad = parseFloat(moveWeight + storeWeight) / parseFloat(this.speed) * parseFloat(this.hourly);
		var loading = roundTo(0.6 * this.fromMultiplier * this.selfLoad * fullLoad + 0.4 * this.toMultiplier * this.selfUnload * fullLoad,5,'up');
		var totalCost = loading + this.drivingCost;
		// if (this.haveTruck == 1 || this.selfLoad == 1) totalCost += this.distance * this.costMile;
		this.moveWeight = moveWeight;
		if (this.entireHome) this.storeWeight = this.moveWeight;
		else this.storeWeight = storeWeight;
		this.storeSize = roundTo(this.storeWeight / 7,5,'up');
		this.totalCost = totalCost;
		var costSpan = new Element('span',{'id':'total-cost','class':'cost'});
		if (this.totalCost + this.totalCost * this.range < this.minQuote) {
			this.totalCost = this.minQuote;
			$('total-cost-advanced').set('html','Minimum Move Price: ');
		}
		else $('total-cost-advanced').set('html','Your Custom Estimate: ');			
		if ($chk(this.allow) && this.firstRun) {
			this.staticTotal = this.totalCost;
			this.staticMove = this.moveWeight;
		}
		if ($chk(this.allow)) {
			this.totalCost = this.staticTotal;
			this.moveWeight = this.staticMove;
			if (this.storeWeight == 0) allowContinue(false);
			else allowContinue(true)
		}				
		$('total-cost-advanced').grab(costSpan);
		$('your-cost').set('html',givePercentageRange(this.totalCost,this.range,'$'));
		if (this.storeWeight == 0) $('your-storage-size').set('html','(add some items)');
		else $('your-storage-size').set('html',getDimensions(this.storeWeight / 7,8));
		$('your-box-cost').set('html',givePercentageRange((this.moveWeight + this.storeWeight) / 7 * boxMultiplier,this.range,'$'));
		$('your-truck').set('html',roundTo((this.moveWeight + this.storeWeight) / 7 / 8 / 6,5,'up') + ' foot');
		var current = lowHigh($('your-cost'));
		move = lowHigh($('your-cost'));
		if ($('your-box-quote').visible()) box = lowHigh($('your-box-cost'));
		var low = add([move[0],box[0]]);
		var high = add([move[1],box[1]]);
		if (this.firstRun && this.storeWeight + this.moveWeight == 0) $('total-cost').set('html','(add some items)');
		else if (low == 0 && high == 0) $('total-cost').set('html',"Less than $50");
		else $('total-cost').set('html','$' + low + ' - $' + high);
		if (!this.firstRun) {
			this.timer = $clear(this.timer);
			this.queue = true;
			this.timer = this.sendUpdates.delay(1500,this);
		}
		else this.firstRun = false;
	};
	
	this.sendUpdates = function() {this.roomsToString()};	
}

function Item(name,id,volume,extra,crew,price) {
	this.name = name;
	this.id = id;
	this.weight = volume * 7;
	this.volume = volume;
	this.quantity = 1;
	this.crew = crew;
	this.extra = extra;
	this.price = price;
}

Hash.implement({
	setQuantity: function(itemId,quantity) {
		this.get(itemId).quantity = quantity;
	},
	getQuantity: function(itemId) {
		return parseInt(this.get(itemId).quantity);
	},
	length: function() {			
		var i = 0;
		this.each(function(item){if ($type(item) == 'object') i++});
		return parseInt(i);
	},
	getObjects: function() {
		var h = new Hash();
		this.each(function(el){if ($type(el) == 'object') h.set(el.id,el)});
		return h;
	}
});

function Room(name,id,dest,label) {
	this.name = name;
	this.id = id;
	if (!$chk(label)) label = name;
	this.label = label;
	this.visible = false;
	this.destination = dest;
	this.baseId = dest + '-' + id + '-' + label;
	this.list = new Hash();
	
	this.numItems = function() {return this.list.length()};

	this.validInput = function(string) {
		if (string == '' || string === null) string = 0;
		var re = /^[0-9]?[0-9]$/
		return re.test(string);
	};
	
	this.updateRooms = function(itemId,num) {
		//new Request({url:'/quote/update/update_room/' + this.id + '/' + this.name + '/' + this.label.underscore() + '/' + itemId + '/' + num,method:'get',async:'false'}).send();
	};
	
	this.bgFade = function(id) {
		$(id).setStyle('background-color',this.fadeFrom);
		var onComplete = function() {$(id).setStyle('background',null)}.bind(this);
		onComplete.delay(300);
	};
	
	this.dim = function(id) {
		new Fx.Morph(id,{duration:'normal',transition:Fx.Transitions.Sine.easeOut}).start({'opacity':[1,.7]});		
	};
	
	this.clearItems = function() {
		if (this.list.length() == 0) return false;
		this.list.getObjects().each(function(item){
			$(this.baseId + '-' + item.id).dispose();
			this.list.erase(item.id);
			if ($chk($('room-' + this.id + '-' + item.id))) $('room-' + this.id + '-' + item.id).removeClass('default-item');
		},this);
		$(this.baseId + '-temp').show();
		this.quote.calculate();
		$('room-' + this.id + '-content').getElements("div[class!=x-corner][class!=clearfix print]").each(function(div){$(div).setProperty('style',null)});
	}
	
	this.update = function(id,quantity) {
		var itemId = new StringTokenizer(id,'-',3).nextToken();
		var contId = this.baseId + '-' + itemId;
		var inputId = contId + '-input';
	 	if (!$chk(quantity)) quantity = $(inputId).value;
 		if (quantity == "") quantity = 0;
		if (quantity < 0 || !this.validInput(quantity)) return false;
		if (quantity != 0) {
			this.list.setQuantity(itemId,parseInt(quantity));
			$(inputId).value = quantity;
			this.bgFade(this.baseId + '-' + itemId);
		}
		else {
			$(contId).dispose();
			this.list.erase(itemId);
			if ($(this.baseId).getElements('input[type=text]').length == 0) $(this.baseId + '-temp').show();
			if ($('room-' + this.id + '-' + itemId) !== null) {
				$('room-' + this.id + '-' + itemId).setProperty('style',null);
				$('room-' + this.id + '-' + itemId).removeClass('default-item');
			}
		}
		this.updateRooms(itemId,quantity);
		this.quote.calculate();
	};	
	
	this.checkInput = function(quantity) {
		if (quantity == "") quantity = 0;
		if (quantity < 0 || !this.validInput(quantity)) return false;
		return true;
	};
	
	this.sendToUpdate = function(e) {
		var input = e.getTarget();
		input.addClass('unsaved');
		focusValue = input.value;
		updateButton(new StringTokenizer(input.id,'-').nextToken(3) + '-update-button');
	};
	
	this.writeItem = function(itemId,quantity) {
		this.list.setQuantity(itemId,quantity);
		var item = this.list.get(itemId);
		var itemId = this.baseId + '-' + item.id;
		if ($(this.baseId + '-temp') !== null) $(this.baseId + '-temp').hide();
		$(this.baseId).getElement('div[class=item-area]').grab(new Element('div',{'id':itemId,'class':'list-column2 end clearfix'}).adopt([
			new Element('span',{'class':'action'}).grab(new Element('input',{'type':'text','value':quantity,'id':itemId + '-input','events':{
				'blur':function(e){this.sendToUpdate(e)}.bind(this),
				'focus':function(){focusValue = $(itemId + '-input').value;$(itemId + '-input').select()},
				'keyup':function(e){if (e.key == 'enter') this.sendToUpdate(e); else $(itemId + '-input').cleanse(99)}.bind(this)
			}})),
			new Element('span',{'class':'name','html':item.name + ' '}).grab(new Element('a',{'href':'#','id':itemId + '-remove-item','html':'(remove all)','events':{'click':function(e){removeItem(e)}}})
		)]));
		this.bgFade(itemId);
		this.updateRooms(item.id,quantity);
	};
	
	this.hasItem = function(itemId,quantity) {
		if (!this.list.has(itemId)) return false;
		var area = $(this.baseId).getElement('div[class=item-area]');
		area.getElements('div').each(function(div,i,list){if (div.id == this.baseId + '-' + itemId) area.scrollTop = Math.floor(area.scrollHeight * (i / list.length))},this);
		this.list.setQuantity(itemId,add(quantity,this.list.getQuantity(itemId)));
		this.bgFade('move-' + this.id + '-' + this.label.underscore() + '-' + itemId);
		$('move-' + this.id + '-' + this.label.underscore() + '-' + itemId + '-input').value = this.list.getQuantity(itemId);
		this.updateRooms(itemId,quantity);
		return true;
	};
	
	this.addItem = function(itemId,quantity) {
		if (this.list.has(itemId)) this.update(itemId,quantity);
		else {
			this.list.set(itemId,clone(this.itemList.get(itemId)));
			if ($chk(quantity)) this.list.get(itemId).quantity = quantity;
		}
	};
}
