﻿function e(type) { return $(document.createElement(type)); }

var TripPlanner = function(options) {
	var _options = $.extend({}, {
		mapID: 'divMap',
		daysID: 'divDays',
		msgID: 'divMessages',
		saveButtonSelector: 'a.save',
		emailButtonSelector: 'a.email',
		printButtonSelector: 'a.print',
		addDayButtonSelector: 'a.addday',
		travelingToSelector: 'div.travelingto',
		fromCitySelector: 'div.travelingfrom input',
		fromStateSelector: 'div.travelingfrom select',
		byAirSelector: 'div.travelingby span.air input',
		byCarSelector: 'div.travelingby span.car input',
		byBikeSelector: 'div.travelingby span.bike input',
		byRVSelector: 'div.travelingby span.rv input',
		startDateSelector: 'div.travelingby input[type=hidden]'
	}, options);

	var _daysDiv = $('#' + _options.daysID);
	var _msgBox = new MessageBox($('#' + _options.msgID));
	var _daysCount = 0;
	var _undelete = null;

	var _saveRequest = null;
	var _dirty = false;

	var _colors = [
		'034f85',
		'726e37',
		'c40b2e',
		'94714b',
		'593f70',
		'b98320',
		'8c3625'
	];

	var _map;
	var _baseIcon;
	var _overlays = [];

	load = function() {
		var loading = e('span').addClass('loading').text('Loading...');
		_msgBox.showMessage(loading, { id: 'load' });
		$.post('/_service/TripPlanner/Get.ashx', {}, loaded, 'json');
	};

	loaded = function(data, status) {
		// TODO: Display error.
		if (status != 'success')
			return;

		for (var x = 0; x < data.length; x++) {
			var item = data[x];
			while (_daysCount <= item.Page)
				createDay();
			appendToDay(item, item.Page);
		}

		while (_daysCount < 5)
			createDay();

		updateNumbers();

		var startDate = $(_options.startDateSelector).val();
		if (startDate)
			updateDates(new Date(Date.parse(startDate)));

		_msgBox.hideMessage('load');
	};

	appendToDay = function(item, dayID) {
		var days = $('div.day', _daysDiv);
		var pos = 1;
		for (var x = 0; x <= dayID; x++)
			pos += $('div.item', days.eq(x)).length;

		var dayDiv = days.eq(dayID);

		var itemDiv = createItem(item, pos);

		var blank = $('div:last', dayDiv)
			.removeClass('blank').addClass('bottomtarg')
			.before(itemDiv);
		fixHeight(itemDiv);
	};

	fixHeight = function(itemDiv) {
		var h = $('div.details', itemDiv).height() + 5;
		$('div.layout', itemDiv).height(h);
		itemDiv.data('oldheight', h);
	};

	findDistance = function(lat1, lon1, lat2, lon2) {
		var x = 69.1 * (lat2 - lat1);
		var y = 53.0 * (lon2 - lon1);

		return Math.sqrt(x * x + y * y);
	};

	createDay = function() {
		var id = _daysCount + 1;
		var dayClass = 'day' + ((_daysCount % 7) + 1);

		var day = e('div').addClass('day').addClass(dayClass);
		day.data('dayid', _daysCount);

		var input;
		var header = e('div').addClass('header')
			.append(e('strong').text('Day ' + id))
			.append(e('span').addClass('date')
				.append(input = e('input').attr('type', 'text').attr('name', 'date'))
			)
			.append(e('span').addClass('drag').text('Drag and Drop Items into Area Below'));

		input.datepicker({
			showOn: 'button',
			buttonImage: '/_images/buttons/tripplanner/bt_calendaricon.gif',
			buttonImageOnly: true,
			onSelect: dateSelected
		});

		day.append(header);

		var blank = e('div')
			.addClass('blank')
			.text('Drag and Drop Items into this Area');
		day.append(blank);

		_daysDiv.append(day);
		_daysCount++;


		blank.droppable({
			hoverClass: 'blankover',
			tolerance: 'pointer',
			drop: dropOnDay
		});
	};

	createLink = function(item) {
		if(item.Type == 'Partner') {
			var url = '/' + item.SuperTag + '/';
			if (item.Alias)
				url += item.Alias + '.dr';
			else
				url += "Details?id=" + item.NodeID;

			return e('a').attr('href', url).text(item.Title);
		}
		if(item.Type == 'Event') {
			return e('a').attr('href', '/Events/Details?id=' + item.NodeID).text(item.Title);
		}
		if(item.Type == 'Package') {
			return e('a').attr('href', '/Vacation-Packages/Details?id=' + item.NodeID).text(item.Title);
		}
		
		return e('span').text(item.Title);
	};

	createItem = function(item, pos) {
		var itemdiv = e('div').addClass('item');

		itemdiv.data('itemdata', item);

		var span = e('span').text(' ');
		var targdiv = e('div').addClass('droptarg')
			.append(span);

		itemdiv.append(targdiv);

		var layout = e('div').addClass('layout');

		layout.append(e('div').addClass('num').text(pos));

		var link = createLink(item);
		var expando = e('a').addClass('expand').attr('href', '#details').text('+ Expand Details');
		layout.append(
			e('div').addClass('details')
				.append(e('h4').append(link))
				.append(e('p').append(expando))
		);
		
		layout.append(
			e('div').addClass('tags')
				.append(e('strong').text(item.SuperTag))
				.append(e('span').text(item.City))
		);

		var dist = e('div').addClass('dist');
		layout.append(dist);

		var book = e('div').addClass('book');
		if (item.InntopiaID) {
			var bookURL;
			if (item.Type == 'Partner') {
				if (item.InntopiaCategoryID == 12) {
					bookURL = 'http://vacations.travelsd.inntopia.travel/aspnet/09/supplier.aspx?salesid=650558&supplierid=' + item.InntopiaID;
				} else {
					bookURL = 'http://vacations.travelsd.inntopia.travel/aspnet/09/search.aspx?salesid=650558&supplierid=' + item.InntopiaID + "&startposition=1&productsupercategoryid=" + item.InntopiaSuperCategoryID;
				}
			} else {
				bookURL = 'http://vacations.travelsd.inntopia.travel/aspnet/09/packageselect.aspx?salesid=650558&packageid=' + item.InntopiaID + '&returnxml=0';
			}
			book.append(e('a')
				.addClass('inntopia')
				.addClass('bookonline')
				.attr('href', bookURL)
				.attr('target', '_blank')
				.text('Book Online')
			);
		} else if (item.BookURL) {
			book.append(e('a')
				.addClass('offsite')
				.attr('href', item.BookURL)
				.attr('target', '_blank')
				.text('Booking Available')
			);
		}
		layout.append(book);

		itemdiv.append(layout);

		var edit = e('div').addClass('edit')
			.append(e('a').addClass('del').attr('href', '#del').text('Delete'))
			.append(e('a').addClass('dupe').attr('href', '#dupe').text('Duplicate'));
		layout.append(edit);

		var grab = e('div').addClass('grab').text('Grab to drag');
		itemdiv.append(grab);

		makeDraggable(itemdiv);
		//makeDraggable(layout);

		return itemdiv;
	};

	makeDraggable = function(itemdiv) {

		var grab = $('div.layout, div.grab', itemdiv);

		grab.bind('mouseover', function() {
			$(this).css({ 'cursor': 'move' });
		}).bind('mouseout', function() {
			$(this).css({ 'cursor': 'default' });
		});

		var opts = {
			handle: grab,
			revert: 'invalid',
			zIndex: 1000,
			helper: 'clone',
			start: function(event, ui) {
				$('div.droptarg', ui.helper).remove();
				$('div.droptarg', this).removeClass('droptarg').addClass('olddroptarg');
				$('div.droptarg').show();
			},
			stop: function() {
				$('div.droptarg').hide();
				$('div.olddroptarg', this).removeClass('olddroptarg').addClass('droptarg');
			},
			appendTo: '#' + _options.daysID
		};

		itemdiv.draggable(opts);

		var span = $('div.droptarg span', itemdiv);
		span.droppable({
			hoverClass: 'droptargover',
			tolerance: 'pointer',
			drop: dropOnItem
		});

		$('a.del', itemdiv).bind('click', deleteClick);
		$('a.dupe', itemdiv).bind('click', dupeClick);
		$('a.expand', itemdiv).bind('click', expandClick);
	}


	// Public API
	this.addItem = function(item) {
		var itemDiv = createItem(item, -1);
		var day = $('div.item:last').closest('div.day');
		if (day.length == 0)
			day = $('div.day').get(0);

		$('div:last', day)
			.removeClass('blank')
			.addClass('bottomtarg')
			.before(itemDiv);
		fixHeight(itemDiv);

		itemDiv.hide();
		itemDiv.slideDown();

		_msgBox.showMessage('Added ' + item.Title, { timeout: 2000 });
		updateNumbers();
		_dirty = true;
	}

	// Moving 
	dropOnDay = function(event, ui) {
		$('div.item').draggable('disable');
		ui.helper.remove();

		var oldDay = $(ui.draggable).closest('div.day');
		var targetDay = $(this).closest('div.day');

		$('div:last', targetDay)
			.removeClass('blank')
			.addClass('bottomtarg')
			.before(ui.draggable);

		checkForBlankDay(oldDay);

		$('div.item').draggable('enable');
		movedMessage(ui.draggable);
		updateNumbers();
		_dirty = true;
	};

	dropOnItem = function(event, ui) {
		$('div.grab').draggable('disable');
		ui.helper.remove();

		var oldDay = $(ui.draggable).closest('div.day');
		var targetDay = $(this).closest('div.day');

		$(this.parentNode.parentNode).before(ui.draggable);

		checkForBlankDay(oldDay);

		$('div.grab').draggable('enable');
		movedMessage(ui.draggable);
		updateNumbers();
		_dirty = true;
	};

	movedMessage = function(itemdiv) {
		var title = $('div.details h4', itemdiv).text();
		_msgBox.showMessage('Moved ' + title, { timeout: 2000 });
	}

	checkForBlankDay = function(day) {
		if ($('div.item', day).length == 0) {
			$('div:last', day)
				.stop().show()
				.removeClass('bottomtarg')
				.addClass('blank');
		}
	};
	// /Moving 
	
	updateNumbers = function() {
		var items = $('div.item', _daysDiv);

		for (var x = _overlays.length - 1; x >= 0; x--)
			_map.removeOverlay(_overlays[x]);
		_overlays = [];

		var last = null;
		var cities = '';
		var cityCount = 0;
		for (var x = 0; x < items.length; x++) {
			var item = items.eq(x);
			var itemData = item.data('itemdata');
			var dayid = item.closest('div.day').data('dayid');
			
			if(itemData.City) {
				var add = itemData.City + '<br />';
				if (cities.indexOf(add) < 0)
					cities += (++cityCount) + '. ' + add;
			}

			$('div.num', item).text(x + 1);
			
			var newDist;
			if (last == null) {
				newDist = e('span').addClass('start').text('Starting Point');
				last = itemData;
			} else {
				if(itemData.Latitude && last.Latitude) {
					var dist = findDistance(
						itemData.Latitude,
						itemData.Longitude,
						last.Latitude,
						last.Longitude
					);

					dist = Math.round(dist * 10) / 10;
					newDist = e('span').addClass('route').text(dist + ' miles');
				} else {
					newDist = e('span');
				}
				
				if(itemData.Latitude)
					last = itemData;
			}
			
			var html = '<b>' + itemData.Title + '</b><br />';
			if (itemData.Address)
				html += itemData.Address + '<br />';
			html += itemData.City + ', SD<br />';
			if (itemData.BookingPhone)
				html += itemData.BookingPhone + '<br />';

			var marker = createMarker(
				new GLatLng(itemData.Latitude, itemData.Longitude),
				x + 1,
				_colors[dayid % 7],
				html
			);
			_map.addOverlay(marker);
			_overlays.push(marker);

			var distDiv = $('div.dist', item).eq(0);
			distDiv.html('').append(newDist);
		}

		if (cities == '')
			cities = 'No destinations yet.  Add some items to your Trip Planner!';
		$(_options.travelingToSelector).html(cities);
	}

	dateSelected = function() {
		var date = $(this).val();
		var dateParsed = null;
		try {
			dateParsed = Date.parse(date);
		} catch (e) { dateParsed = null; }
		if (dateParsed == null)
			return;

		var dayID = $(this).closest('div.day').data('dayid');
		var startDate = new Date(dateParsed);
		startDate.setDate(startDate.getDate() - dayID);

		updateDates(startDate);

		_dirty = true;
	};

	updateDates = function(startDate) {
		var days = $('div.day', _daysDiv);
		for (var x = 0, m = days.length; x < m; x++) {
			var formatted = (startDate.getMonth() + 1) + '/' +
				startDate.getDate() + '/' +
				startDate.getFullYear();
			$('span.date input', days.eq(x)).val(formatted);
			startDate.setDate(startDate.getDate() + 1);
		}
	};

	// Del and Dupe
	deleteClick = function() {
		var item = $(this).closest('div.item');
		var day = $(this).closest('div.day');

		_undelete = {
			item: item,
			day: day,
			itemdata: item.data('itemdata')
		};

		var title = $('div.details h4', item).text();
		var undo = e('a').attr('href', '#undo').text('Click to undelete.')
			.bind('click', undoDelete);

		var msg = e('span').addClass('del')
			.text('Removed ' + title + ' ')
			.append(undo);
		_msgBox.showMessage(msg, { timeout: 5000, id: 'deleted' });

		item.remove();

		checkForBlankDay(day);
		updateNumbers();
		_dirty = true;

		return false;
	};

	undoDelete = function() {
		_msgBox.hideMessage('deleted');

		_undelete.item.data('itemdata', _undelete.itemdata);
		$('div:last', _undelete.day).removeClass('blank').addClass('bottomtarg')
			.before(_undelete.item);

		makeDraggable(_undelete.item);

		updateNumbers();
		_dirty = true;

		return false;
	};

	dupeClick = function() {
		var item = $(this).closest('div.item');

		var newItem = item.clone(false);
		newItem.data('itemdata', item.data('itemdata'));
		makeDraggable(newItem);

		item.after(newItem);

		var title = $('div.details h4', item).text();
		var msg = e('span').addClass('dupe').text('Duplicated ' + title + ' '); //.append(undo);

		_msgBox.showMessage(msg, { timeout: 2000 });
		updateNumbers();
		_dirty = true;

		return false;
	};

	expandClick = function() {
		var item = $(this).closest('div.item');
		var nodeID = item.data('itemdata').NodeID;
		var type = item.data('itemdata').Type;

		$('div.details p', item).html('Loading....');

		$.get('/_service/TripPlanner/Details.ashx', { id: nodeID, type: type }, function(data, status) {
			expandDetailsCallback(data, status, item);
		}, 'json');

		return false;
	};

	expandDetailsCallback = function(data, status, item) {
		if (status != 'success')
			return;
		var details = $('div.details', item);

		$('p', details).remove();

		var newHeight = $('h4', details).height() + 70;

		if (data.Address) {
			var addr = e('p').text(data.Address);
			details.append(addr);
			newHeight += addr.height();
		}
		if(data.Dates) {
			var dates = e('p').text(data.Dates);
			details.append(dates);
			newHeight += dates.height();
		}
		if (data.Description) {
			var desc = e('p').text(data.Description);
			details.append(desc);
			newHeight += desc.height();
		}
		if (data.Tags) {
			var tags = e('p').text("Tags: " + data.Tags);
			details.append(tags);
			newHeight += tags.height();
		}

		var link = e('p').append(
			e('a').attr('href', '#close')
				.text('- Close details')
				.bind('click', closeDetailsClick)
		);

		details.append(link);

		$('div.layout', item).animate({ height: newHeight + 'px' }, 500);
	};

	closeDetailsClick = function() {
		var item = $(this).closest('div.item');
		var oldHeight = item.data('oldheight');

		var details = $('div.details', item);
		$('p', details).remove();
		$('div.layout', item).animate({ height: oldHeight + 'px' }, 500);

		details.append(
			e('p').append(
				e('a').attr('href', 'expand')
					.bind('click', expandClick)
					.text('+ Expand Details')
			)
		);

		return false;
	};
	// /Del and Dupe

	// Save
	save = function(callback) {
		if (_saveRequest != null) {
			_msgBox.showMessage('Save in progress, please wait', { timeout: 2000 });
			return false;
		}

		_saveRequest = {};
		_dirty = false;

		var itemsdata = [];

		var items = $('div.item', _daysDiv);
		for (var x = 0; x < items.length; x++) {
			var data = items.eq(x).data('itemdata');
			var day = items.eq(x).closest('div.day');

			itemsdata.push({
				NodeID: data.NodeID,
				Page: day.data('dayid')
			});
		}

		var postdata = {
			cart: JSON.stringify(itemsdata),
			city: $(_options.fromCitySelector).val(),
			state: $(_options.fromStateSelector).val(),
			start: $('div.day:first span.date input').val()
		};

		if ($(_options.byAirSelector).attr("checked"))
			postdata.byair = 1;
		if ($(_options.byCarSelector).attr("checked"))
			postdata.bycar = 1;
		if ($(_options.byBikeSelector).attr("checked"))
			postdata.bybike = 1;
		if ($(_options.byRVSelector).attr("checked"))
			postdata.byrv = 1;

		_saveRequest = $.post('/_service/TripPlanner/Save.ashx', postdata, callback, 'json');

		return true;
	};

	saveClick = function() {
		if ($(this).attr('href') != '#save')
			return true;

		var showMsg = save(saveCallback);
		if (showMsg) {
			var loading = e('span').addClass('loading').text('Saving...');
			_msgBox.showMessage(loading, { id: 'save' });
		}

		return false;
	};

	saveCallback = function() {
		_msgBox.hideMessage('save');
		_msgBox.showMessage('Your list has been saved.', { timeout: 2000 });
		_saveRequest = null;
	};

	autoSaveCallback = function() {
		// _msgBox.showMessage('Your list has been auto-saved.', { timeout: 2000 });
		_saveRequest = null;
	};

	autoSaveTick = function() {
		if (_dirty && _saveRequest == null) {
			save(autoSaveCallback);
		}
	};
	// /Save


	// MAP
	function createMap() {
		_map = new GMap2(document.getElementById(_options.mapID));
		_map.setCenter(new GLatLng(44.43377984606822, -100.3271484375), 7);
		_map.setUIToDefault();
		_map.disableScrollWheelZoom();

		_baseIcon = new GIcon(G_DEFAULT_ICON);
		_baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
		_baseIcon.iconSize = new GSize(20, 34);
		_baseIcon.shadowSize = new GSize(37, 34);
		_baseIcon.iconAnchor = new GPoint(9, 34);
		_baseIcon.infoWindowAnchor = new GPoint(9, 2);
	}

	function createMarker(point, display, bgcol, desc) {
		// Create a lettered icon for this point using our icon class
		var Icon = new GIcon(_baseIcon);
		Icon.image = "http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=" + display + "|" + bgcol + "|ffffff";

		// Set up our GMarkerOptions object
		markerOptions = { icon: Icon };
		var marker = new GMarker(point, markerOptions);

		GEvent.addListener(marker, "click", function() {
			marker.openInfoWindowHtml('<p align="left">' + desc + '</p>');
		});
		return marker;
	};
	// /MAP

	emailClick = function() {
		var email = prompt('Where would you like to email this?');
		if (email) {
			var data = { email: email };

			$.post('/_service/TripPlanner/Email.ashx', data, emailSent, 'json');
		}
		return false;
	};

	emailSent = function(data, status) {
		// TODO: Display error.
		if (status != 'success')
			return;

		_msgBox.showMessage('Your list has been sent to: ' + data.SentTo, { timeout: 2000 });
	};

	printClick = function() {
		var pop = window.open(this.getAttribute('href'), 'popup', 'width=700,height=500,status=yes,scrollbars=yes,resizable=1');
		if (pop == null || typeof (pop) == "undefined") {
			return true;
		} else {
			return false;
		}
	};

	addDayClick = function() {
		createDay();

		var first = $('div.day:first span.date input', _daysDiv).val();
		var date = null;
		if (first) {
			try {
				date = Date.parse(first);
			} catch (e) { date = null; }
			if (date)
				updateDates(new Date(date));
		}

		return false;
	};

	createMap();
	load();
	$(_options.saveButtonSelector).bind('click', saveClick);
	$(_options.emailButtonSelector).bind('click', emailClick);
	$(_options.printButtonSelector).bind('click', printClick);
	$(_options.addDayButtonSelector).bind('click', addDayClick);
}


var MiniSearch = function(options) {
	var _options = $.extend({}, {
		citiesID: 'dropCities',
		milesID: 'dropMiles',
		groupID: 'dropGroups',
		tagsID: 'dropTags',
		hiddenTagsID: 'hidTags',
		resultsID: 'divResults',
		resultsHeader: 'divResultsHeader',
		addClick: null
	}, options);
	
	var _citiesDiv = $('#' + _options.citiesID);
	var _milesDiv = $('#' + _options.milesID);
	var _groupDiv = $('#' + _options.groupID);
	var _tagsDiv = $('#' + _options.tagsID);
	var _resultsHeader = $('#' + _options.resultsHeader);
	var _tags = { };
	var _resultsDiv = $('#' + _options.resultsID);
	var _tagsClone = _tagsDiv.clone(false);
	
	var _request = null;
	var _lastQuery = null;
	var _currentQuery = null;
	
	var groupChanged = function() {
		var newTags = _tagsClone.clone(false);
		var newParentID = parseInt(_groupDiv.val(), 10);
		
		if(newParentID > 0) {
			var kids = $('option', newTags);
			for(var x=kids.length - 1; x >=0; x--) {
				var option = kids.eq(x);
				var id = option.attr('value');
				if(_tags[id] != newParentID)
					option.remove();
				else
					option.attr('selected', true);
			}
		}
		
		_tagsDiv.replaceWith(newTags);
		_tagsDiv = newTags;
		_tagsDiv.bind('change', tagChanged);
		if(newParentID > 0) {
			tagChanged();
		}
	};
	
	var tagChanged = function() {
		_currentQuery = {
			cityID: _citiesDiv.val(),
			dist: _milesDiv.val(),
			tags: _tagsDiv.val()
		};
	};
	
	var fireRequest = function() {
		if(_request == null && _currentQuery != null && _currentQuery.tags && _currentQuery.tags.length) {
			_request = {};
			
			var change = _lastQuery == null ||
				_currentQuery.cityID != _lastQuery.cityID ||
				_currentQuery.dist != _lastQuery.dist ||
				_currentQuery.tags.length != _lastQuery.tags.length;
			
			for(var x=0; !change && x<_currentQuery.tags.length; x++) {
				if(_currentQuery.tags[x] != _lastQuery.tags[x])
					change = true;
			}
			
			if(!change) {
				_request = null;
				return;
			}
			
			_lastQuery = _currentQuery;
			
			_resultsHeader.addClass('loading');
			_request = $.get('/_service/TripPlanner/Search.ashx', _lastQuery, resultsReturned, 'json');
		}
	};
	
	var resultsReturned = function(data, status) {
		// TODO: Display error.
		if(status != 'success') {
			_request = null;
			return;
		}
		
		if(data.length == 0) {
			var noneDiv = e('div').addClass('none').text('No Results');
			_resultsDiv.html('');
			_resultsDiv.append(noneDiv);
			_resultsHeader.removeClass('loading');
			
			_request = null;
			return;
		}
		
		var table = e('table').append(e('tbody'));
		table.attr('cellpadding', '0')
			.attr('cellspacing', '0');
		
		for(var x=0; x<data.length; x++) {
			var add;
			var tr = e('tr')
				.append(e('td').addClass('num').text((x + 1) + '.'))
				.append(e('td').addClass('name').text(data[x].Title))
				.append(e('td').addClass('city').text(data[x].City))
				.append(e('td').addClass('add').append(
					add = e('a').addClass('button').attr('href', '#add').text('Add')
				));
			if((x % 2) == 0)
				tr.addClass('alt');
			add.bind('click', addOnClick);
			tr.data('itemdata', data[x]);
			table.append(tr);
		}
		
		_resultsDiv.html('');
		_resultsDiv.append(table);
		_resultsHeader.removeClass('loading');
		
		_request = null;
	};
	
	var addOnClick = function() {
		if(_options.addClick) {
			var itemdata = $(this).closest('tr').data('itemdata');
			_options.addClick(itemdata);
		}
		return false;
	};
	
	// Presort tags
	var rawTags = JSON.parse($('#' + _options.hiddenTagsID).val());
	for(var x=rawTags.length - 1; x>=0; x--) {
		var parent = rawTags[x].ParentTagID;
		var tag = rawTags[x].TagID;
		
		_tags[tag] = parent;
	}
	
	_groupDiv.bind('change', groupChanged);
	
	_tagsDiv.bind('change', tagChanged);
	_citiesDiv.bind('change', tagChanged);
	_milesDiv.bind('change', tagChanged);
	setInterval(fireRequest, 250);
	setInterval(autoSaveTick, 500);
}
