var Order = new Class({
	Implements: [Options],

	options: {
		stdDays: [],
		expDays: [],
		months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
		packages: {
			webpage: {
				professional: {
					cd_coding			: 'w3c_strict_xhtml',
					cd_tableless	: 'yes',
					c_opera				: 'yes',
					c_safari			: 'yes',
					css_w3c				: 'yes',
					cd_wai				: 'yes'
				},
				expert: {
					cd_coding			: 'w3c_strict_xhtml',
					cd_tableless	: 'yes',
					c_opera				: 'yes',
					c_safari			: 'yes',
					css_w3c				: 'yes',
					cd_wai				: 'yes',
					cd_seo				: 'yes',
					cd_speed			: 'yes'
				}
			}
		},
		features: {
			featured: {
				cd_wai					: 'yes'
			}
		},
		checkedFeaturesPrefix: 'checked_',
		webPageBasePrice: 0,
		emailTemplateBasePrice: 0,
		webPagePrices: {},
		emailTemplatePrices: {},
		//templateTypeId: 'template-type',
		templateTypeWeb: 'webpage',
		templateTypeEmail: 'email',
		amountId: 'amount',
		formId: 'order',
		pagesId: 'order-pages',
		implementationOptionPrefix: 'i_engine_',
		pricePrefix: 'price_',
		currencySign: '$',
		includedString: 'included',
		samePriceString: 'same price',
		expandButtonClass: 'expand-option-link',
		expandedOptionClass: 'expand-option',
		expeditedId: 'order-expedited',
		estDeliveryId: 'order-est-delivery',
		timelineNoteId: 'timeline-note',
		implementationNoteId: 'implementation-note',
		textExpeditedDeliveryId: 'text-expedited-delivery',
		optionClass: 'checkbox',
		debug: false
	},

	initialize: function(options) {
		this.setOptions(options);
		this.basePrice = {};
		this.prices = {};
		this.activePackage = {};
		this.opts = {};
		this.form = $(this.options.formId);
		//this.templateType = true; //$(this.options.templateTypeId);
		this.activeTemplate = this.options.templateTypeWeb;
		this.pages = $(this.options.pagesId);
		this.amount = $(this.options.amountId);
		this.expedited = $(this.options.expeditedId);
		this.estDelivery = $(this.options.estDeliveryId);
		this.timelineNote = $(this.options.timelineNoteId);
		this.implementationNote = $(this.options.implementationNoteId);
		this.textExpeditedDelivery = $(this.options.textExpeditedDeliveryId);
		if(this.form && this.pages) {
			this.basePrice[this.options.templateTypeWeb] = this.options.webPageBasePrice;
			this.basePrice[this.options.templateTypeEmail] = this.options.emailTemplateBasePrice;
			this.prices[this.options.templateTypeWeb] = this.options.webPagePrices;
			this.prices[this.options.templateTypeEmail] = this.options.emailTemplatePrices;
			this.activePackage[this.options.templateTypeWeb] = null;
			this.activePackage[this.options.templateTypeEmail] = null;
			this.opts[this.options.templateTypeWeb] = {};
			this.opts[this.options.templateTypeEmail] = {};
			//this.initTemplate();
			this.initExpandButtons();
			this.initOptions();
			this.initPackages();
			this.initFeatures();
			this.initPages();
			this.initExpedite();
			//this.selectTemplate(this.templateType.value);
			this.calculatePrice();
		}
		else {
			this.log('Invalid form id, template type id or pages id');
		}
	},

	initExpandButtons: function() {
		$$('.' + this.options.expandButtonClass).each(function(item) {
			item.href = 'javascript:;';
			item.addEvent('click', (function(event, self) {
				var node = $(this.rel);
				if(node) {
					node.toggleClass(self.options.expandedOptionClass);
				}
				return false;
			}).bindWithEvent(item, this));
		}, this);
	},

	initOptions: function () {
		// WebPage Options
		$$('#' + this.options.templateTypeWeb + ' input.' + this.options.optionClass + '[type=checkbox]').each(function(item) {
			this.opts[this.options.templateTypeWeb][item.getProperty('id')] = true;
			item.addEvent('click', (function(event, self) {
				//var item = $(this);
				//self.selectFeaturesReverse(item.getProperty('name'), item.getProperty('checked'));
				//self.fillOrderExpedited(parseInt(self.pages.value));
				self.calculatePrice();
			}).bindWithEvent(item, this));
		}, this);
		// WebPage Options Implimentator
		$$('#' + this.options.templateTypeWeb + ' input.radio[type=radio]').each(function(item) {
			this.opts[this.options.templateTypeWeb][item.getProperty('id')] = true;
			item.addEvent('click', (function(event, self) {
				self.calculatePrice();
			}).bindWithEvent(item, this));
		}, this);
	},

	initPackages: function() {
		for(var template in this.options.packages) {
			for(var pkg in this.options.packages[template]) {
				var pack = $(pkg);
				if(pack) {
					pack.addEvent('click', (function(event, self) {
						self.selectPackage(this.id);
						self.calculatePrice();
					}).bindWithEvent(pack, this));
					if(pack.getProperty('checked')) {
						this.activePackage[template] = pkg;
					}
				}
			}
		}
	},

	initFeatures: function() {
		for(var featured in this.options.features) {
			element = $(featured);
			if(element) {
				element.addEvent('click', (function(event, self) {
					var element = $(this);
					self.selectFeatures(element.getProperty('id'), element.getProperty('checked'));
					self.calculatePrice();
				}).bindWithEvent(element, this));
			}
		}
	},

	initPages: function() {
		this.pages.addEvents({
			keyup: (function() {
				this.pages.value = this.pages.value.trim();
				if(this.pages.value) {
					if(isNaN(this.pages.value) || Number(this.pages.value) < 1) {
						this.pages.value = 1;
					}
					this.pages.value = parseInt(this.pages.value);
					//this.fillOrderExpedited(this.pages.value);
					this.calculatePrice();
				}
			}).bind(this),
			change: (function() {
				this.pages.value = this.pages.value.trim();
				if(this.pages.value) {
					if(isNaN(this.pages.value) || Number(this.pages.value) < 1) {
						this.pages.value = 1;
					}
					this.pages.value = parseInt(this.pages.value);
					//this.fillOrderExpedited(this.pages.value);
					this.calculatePrice();
				}
			}).bind(this)
		});
		/*
		if(this.expedited) {
			this.expedited.addEvent('change', (function() {
				this.calculatePrice();
			}).bind(this));
			this.fillOrderExpedited(parseInt(this.pages.value));
		}
		*/
	},

	initExpedite: function() {
		if(this.expedited) {
			this.expedited.addEvent('change', (function() {
				this.calculatePrice();
			}).bind(this))
		}
	},

	selectPackage: function(name) {
		this.log('Select package: ' + name);
		for(var option in this.opts[this.activeTemplate]) {
			var element = $(option);
			if(element) {
				var set = this.form.elements[element.name];
				var pkg = this.options.packages[this.activeTemplate][name];
				if(set && pkg) {
					var v = pkg[element.name];
					if(v)
					{
						set.checked = true;
					}
					else
					{
						set.checked = false;
					}
				}
			}
		}
		this.activePackage[this.activeTemplate] = name;
		this.reselectFeatures();
	},

	selectFeatures: function(name, checked) {
		if(this.options.features[name]) {
			for(var option in this.options.features[name]) {
				var set = this.form.elements[option];
				for(var i = 0; i < set.length; i++) {
					if(set[i].value == this.options.features[name][option]) {
						set[i].checked = checked;
						break;
					}
				}
				if(!checked && set[0]) {
					set[0].checked = true;
				}
				var featured = $(name);
				if(featured) {
					featured.setProperty('checked', checked);
				}
				var checkedFeatures = $(this.options.checkedFeaturesPrefix + name);
				if(checkedFeatures) {
					checkedFeatures.setProperty('value', checked? 'yes': 'no');
				}
			}
		}
	},

	selectFeaturesReverse: function(name, checked) {
		var featured = false;
		for(var features in this.options.features) {
			if(this.options.features[features][name]) {
				featured = features;
				break;
			}
		}
		if(featured) {
			var element = $(featured);
			if(element) {
				element.setProperty('checked', checked);
			}
			var checkedFeatures = $(this.options.checkedFeaturesPrefix + featured);
			if(checkedFeatures) {
				checkedFeatures.setProperty('value', 'no');
			}
		}
	},

	reselectFeatures: function() {
		for(var features in this.options.features) {
			var featured = $(features);
			if(featured) {
				this.selectFeatures(features, featured.getProperty('checked'));
			}
		}
	},

	calculatePrice: function() {
		var implementationCost = 0;
		var totalCost = this.basePrice[this.activeTemplate];
		for(var option in this.opts[this.activeTemplate]) {
			var element = $(option);
			if(element) {
				if(element.getProperty('checked')) {
					if(this.prices[this.activeTemplate][option]) {
						this.log('Added ' + option + ':' + element.getProperty('checked'));
						if(option.indexOf(this.options.implementationOptionPrefix) == 0) {
							implementationCost = this.prices[this.activeTemplate][option];
						}
						else {
							totalCost += this.prices[this.activeTemplate][option];
						}
					}
				}
				else {
					continue;
				}
			}
		}
		this.pages.value = this.pages.value.trim();
		var pages = this.pages.value;
		if(!(isNaN(pages) || Number(pages) < 1)) {
			pages = parseInt(pages);
		}
		if(pages > 1) {
			totalCost += totalCost * (pages - 1) / 2;
		}
		if(this.expedited && this.estDelivery) {
			var pageIndex;
			if(this.options.expDays[pages - 1]) {
				pageIndex = pages - 1;
				var expeditedDays = 0;
				if(!implementationCost) {
					if(this.expedited.value == 'asap') {
						expeditedDays = this.options.expDays[pageIndex]['expETADays'];
					}
					else if(this.expedited.value != 'no') {
						expeditedDays = parseInt(this.expedited.value);
					}
					this.log('Expedited days: ' + expeditedDays);
				}
				var workingHours;
				var businessDays;
				var deliveryDate;
				if(expeditedDays) {
					businessDays = this.options.expDays[pageIndex]['stdETADays'] - expeditedDays;
					workingHours = this.options.stdDays[businessDays - 1]['stdWorkingHours'];
					totalCost += totalCost * expeditedDays / this.options.expDays[pageIndex]['stdETADays'];
				}
				else {
					businessDays = this.options.expDays[pageIndex]['stdETADays'];
					workingHours = this.options.expDays[pageIndex]['stdWorkingHours'];
				}
				deliveryDate = this.addWorkingDays(businessDays);
				this.estDelivery.set('html', '<strong>' + this.options.months[deliveryDate.getMonth()] + '-' + deliveryDate.getDate() + '</strong> / ' + workingHours + ' working hrs / ' + businessDays + ' business day' + (businessDays == 1? '': 's'));
				this.log('Delivery date: ' + deliveryDate);
			}
			else {
				this.estDelivery.set('html', '<strong>Custom, Optimized</strong>');
				this.amount.set('html', 'Custom, Discounted');
				return;
			}
		}
		totalCost = Math.floor(totalCost + implementationCost);
		this.amount.set('html', this.options.currencySign + totalCost);
		if(this.timelineNote && this.implementationNote) {
			if(implementationCost) {
				this.timelineNote.addClass('hidden');
				this.implementationNote.removeClass('hidden');
			}
			else {
				this.timelineNote.removeClass('hidden');
				this.implementationNote.addClass('hidden');
			}
		}
		if(this.textExpeditedDelivery) {
			if(this.expedited.value == 'no') {
				this.textExpeditedDelivery.removeClass('bold');
			}
			else {
				this.textExpeditedDelivery.addClass('bold');
			}
		}
		this.log('Total cost: ' + totalCost);
	},

	fillOrderExpedited: function(pages) {
		var implementation = false;
		for(var option in this.opts[this.activeTemplate]) {
			var element = $(option);
			if(element && element.getProperty('checked') && option != 'i_engine_1' && option.indexOf(this.options.implementationOptionPrefix) == 0) {
				implementation = true;
				break;
			}
		}
		var selected = this.expedited.value;
		this.expedited.empty();
		new Element('option', {
			'value': 'no',
			'html': 'no',
			'selected': selected == 'no'? 'selected': ''
		}).inject(this.expedited);
		if(this.options.expDays[pages - 1] && !implementation) {
			for(var i = 1; i <= expDays[pages - 1]['expETADays']; i++) {
				new Element('option', {
					'value': i,
					'html': 'yes, by ' + i + ' business day' + (i == 1? '': 's'),
					'selected': selected == i? 'selected': ''
				}).inject(this.expedited);
			}
		}
		new Element('option', {
			'value': 'asap',
			'html': 'yes, as soon as possible; get back to me!',
			'selected': selected == 'asap'? 'selected': ''
		}).inject(this.expedited);
	},

	isDST: function(date) {
		var amountmerDate = new Date(date.getFullYear(), 6, 1);

		return amountmerDate.getTimezoneOffset() == date.getTimezoneOffset();
	},

	isHoliday: function(date) {
		var dayOfWeek = date.getDay();
		var day = date.getDate();
		var month = date.getMonth();

		return dayOfWeek == 0 || dayOfWeek == 6 ||
          (day == 1 && month == 0) ||
          (day == 2 && month == 0) ||
          (day == 8 && month == 2) ||
          (day == 9 && month == 4) ||
          (day == 24 && month == 7) ||
          (day == 31 && month == 11);
	},

	addWorkingDays: function(days) {
		var i = 0;
		var daysToAdd = 0;

		var now = new Date();
		var date = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours() + (now.getUTCSeconds()? 1: 0) - (this.isDST(now)? 0: 1), 0, 0);

		var hours = date.getHours();
		var isHoliday = this.isHoliday(date);
		if(hours <= 9 || hours > 17 || isHoliday) {
			if(hours <= 9 && !isHoliday && days) {
				days--;
			}
			date.setHours(17);
		}

		var timestamp = date.getTime();
		while(i < days) {
			daysToAdd++;
			tempDate = new Date(timestamp + daysToAdd * 24 * 60 * 60 * 1000);
			if(this.isHoliday(tempDate)) {
				days++;
			}
			i++;
		}

		return new Date(timestamp + daysToAdd * 24 * 60 * 60 * 1000);
	},

	log: function(text, args) {
		if(this.options.debug && window.console) console.log(text.substitute(args || {}));
	}
});
