/**
 * Current property state tracking
 * Sagan Bolliger, 29 June 2011
 */

Property = new function() {
	/**
	 * Clears the current properties list.
	 */
	this.clearProperties = function() {
		propertyList = {};
	};
	/**
	 * Returns the dictionary of field names to field values for the 
	 * property with the specified id.
	 */
	this.getFieldsForId = function(id) {
		return propertyList[id];
	};
	/**
	 * Accepts a template item and populates
	 * its data-field tags with the fields for the property
	 * specified by id. data-property-id is set. Newly populated 
	 * node is returned ready for DOM insertion.
	 */
	this.populateFieldsForItem = function(item,id) {

		item.attr('data-property-id',id);
		
		var fieldDictionary = Property.getFieldsForId(id);

		$.each(fieldDictionary,function(fieldName,fieldValue) {
			$(item).find('[data-field=' + fieldName + ']').each(function(idx,item) {
				
				var item = $(item);
				
				if(fieldValue == '') {
					item.hide()
					return true;
				} else
					item.show();
				
				Property.populateField(item,fieldValue);
			});
		});
		
		var currentOffer = null;
		var firstOffer = null;
		
		/* populate offers popup */
		if ($(item).find('.offers').length == 1) {
			$(item).find('.offers').html('');
			// there is an offers section to populate
			$.each(fieldDictionary['offers'],function(offer_id,offerFields) { 
				if (!firstOffer) {
					firstOffer = offer_id;
				}
				var offer = $(document.createElement('div'));
				offer.addClass('offer'); 
				offer.attr('data-offer-id',offer_id);
				offer.html(offerFields['short_description']);
				$(item).find('.offers').append(offer);
				if (offerFields['current']) {
					currentOffer = offer_id;
				}
			});
			
			/* try to recover from no current offer condition */
			if (!currentOffer && firstOffer) {
				currentOffer = firstOffer;
			}
		}

		if (currentOffer) {
			var offerItem = $(item).find('[data-offer-id="' + currentOffer + '"]');
			$(offerItem).addClass('active');
			Property.populateOffer(item,currentOffer);
			// NOTE: we let populateOffer set the full-width class TODO
		} else if (typeof fieldDictionary['rates_from'] == "undefined") {
			/* clear fields */
			$(item).find('.rates-from-value, .rates-from').hide();
			$(item).find('.description').addClass('full-width');
		} else {
			$(item).find('.description').removeClass('full-width');
			$(item).find('.rates-from-value, .rates-from').show();
		}

		/* no need to show additionald dates button if there are no
		 * additional dates */
		var additionalDates = $(item).find('.additional-dates');

		if(Property.getAssocArraySize(fieldDictionary['offers']) <= 1 && additionalDates.length) {
			additionalDates.hide();
		} else {
			additionalDates.show();
		}


		/* initialize calendar widgets */
		$(item).find('.booking input.check-in').datepicker({ 
			dayNamesMin: ['SUN', 'MON','TUE','WED','THU','FRI','SAT'],
			showOtherMonths: true,
			dateFormat: 'mm-dd-yy',
			minDate: '0'
		});

		/* populate gallery if it is present */
	
		var images = $(item).find('.gallery .images');
		
		if(images.length) {
			images.html('');
			var firstImg = true;
			$.each(fieldDictionary['gallery'],function(idx,val) {
				var img = $('<img/>');
				img.attr('src',val);
				if(firstImg) {
					firstImg = false;
					img.addClass('active');
				}
				images.append(img);
			});
		}

		return item;
	};
	this.populateField = function(field,fieldValue) {
		if(field.is('img'))
			field.attr('src',fieldValue);
		else if(field.is('a'))
			field.attr('href',fieldValue);
		else if(field.is('input'))
			field.attr('value',fieldValue);
		else if(field.is('form'))
			field.attr('action',fieldValue);
		else
			field.html(fieldValue);
	}
	/**
	 * Set all offer-dependant fields to the values that correspond to the
	 * offer offer_id.
	 */
	this.populateOffer = function(item,offer_id) {
		var item = $(item);
		var propertyId = item.attr('data-property-id');
		var offer = propertyList[propertyId]['offers'][offer_id];

		$.each(offer,function(fieldName,fieldValue) {
			var field = item.find('[data-field=' + fieldName + ']');
			Property.populateField(field,fieldValue);
		});
		
		if(offer['rates_from']) {
			item.find('.rates-from, .rates-from-value').show();
			$(item).find('.description').removeClass('full-width')
		} else {
			item.find('.rates-from, .rates-from-value').hide();
			$(item).find('.description').addClass('full-width')
		}

		if (offer['current']) {
			var sd = new Date();
		}
		else if (offer['start_date'] !== null) {
			var sd = new Date(offer['start_date']);
		}
		else {
			var sd = null;
		}

		if (sd && sd < new Date()) {
			sd = new Date();
		}

		var gap = typeof offer['free_night'] !== 'undefined' ? offer['free_night'] : 1;

		function pad(number, length) {
			var str = '' + number;
			while (str.length < length)
				str = '0' + str;
			return str;
		}
		
		if(sd) {
			var ed = new Date(sd.getFullYear(),
								sd.getMonth(),
								sd.getDate() + parseInt(gap));

			item.find('input.check-in').val(pad(Number(sd.getMonth() + 1),2) + '-' +
										pad(sd.getDate(),2) + '-' + 
										sd.getFullYear());
			
			item.find('input.check-in').attr('gap', gap);
			
			item.find('select.numberOfNights').val(gap);
			
			// item.find('input.check-out').val(pad(Number(ed.getMonth() + 1),2) + '-' +
										// pad(ed.getDate(),2) + '-' + 
										// ed.getFullYear());
		}
		
	}
	/**
	 * Returns any array of items ready for dom insertion based on the 
	 * template provided populated with the current list of properties.
	 */
	this.getItemsForTemplate = function(template) {
		var items = [];
		
		$.each(propertyList,function(propertyId,propertyData) {
			var current = $(template).clone(true); 
			Property.populateFieldsForItem(current,propertyId);
			$(current).removeClass('template');
			items.push(current);
		});
		
		return items;
	}
	/**
	 * Populates the provided view with the items in propertyList using
	 * the contained template.
	 */
	this.populateView = function(view, callback) {
//		var items = Property.getItemsForTemplate($(view).find('.template'));

		var viewName = $(view).attr('data-view-name');
		
		var count = 0;
		
		$.each(propertyList,function(propertyId,propertyData) {
			var campaign_id = propertyData['campaign_id'];
			count++;
			
			$.get('/item/campaign/' + campaign_id + '/view/' + viewName,{}, function(responseText) {
				var templ = $(responseText);
				
				Property.populateFieldsForItem(templ,propertyId);
				$(templ).removeClass('template');
				$(view).append(templ);
				
				count--;
				if(count == 0 && callback)
					callback();
			});
		});

	};
	/*
	 * Adds markers in Map for each property in propertyList
	 */
	this.populateMarkers = function() {
		Map.clearMarkers();
		
		$.each(activeIds,function(idx,id) {
			var longitude = propertyList[id]['longitude'];
			var latitude = propertyList[id]['latitude'];
			var title = propertyList[id]['title'];
			
			Map.addMarker(id,title,latitude,longitude);
		})
	};
	/*
	 * Searches all properties in propertyList for str and places the ids of
	 * properties that match str in activeIds
	 */
	this.performQuery = function(str) {
		var queries = str.split(' '); // get array of words
		activeIds = [];
		
		$.each(propertyList,function(propertyId,propertyData) {
			if(str.length == 0) {
				activeIds.push(propertyId);
				return true; // continue
				// we want to include all results if the query string is empty
			}
			
			$.each(queries,function(idx,thisQuery) {
				// skip words with length two of less
				if(thisQuery.length <= 2)
					return true; // continue
				if((String(propertyData['searchable'])).toLowerCase().indexOf(thisQuery.toLowerCase()) != -1) {
					activeIds.push(propertyId);
					return false; // break
				}
			});
			
		});
	};
	this.getActiveIds  = function() {
		return activeIds;
	}
	/*
	 * Sets the visibility of each item in the provided view according to 
	 * whether it is present in activeIds
	 */
	this.filterViewByActiveIds = function(view) {
		$(view).children('.item[data-property-id]').each(function(idx,item) {
			if($.inArray(($(item).attr('data-property-id')),activeIds) != -1)
				$(item).show();
			else
				$(item).hide();
		});
	}
	/**
	 * Queries the server with the passed location code and updates the list
	 * of properties with the result. If callback is provided,
	 * it is executed when the server query has completed.
	 */
	this.switchToCity = function(locationQuery,callback) {
		currentLocationQuery = locationQuery;
		
		var path = '/properties/';
		if(typeof(id_campaign) != 'undefined')
			path += 'campaign/' + id_campaign + '/';
		if(typeof brand_url_string != 'undefined')
			path += 'brand/' + brand_url_string + '/';
		path += locationQuery;
		
		$.getJSON(path ,{},
			function(data) {
				
				propertyList = data['properties'];
				
				// set the active ids to the full set of ids for the country
				Property.performQuery('');

				Property.populateMarkers();
				
				if(callback)
					callback(data);
			}
		);

	};
	this.getAssocArraySize = function(arr) {
		var size = 0;
		for(var k in arr) {
			if(arr.hasOwnProperty(k))
				size++;
		}
		return size;
	};
	this.getCampaignIdForProperty = function(id) {
		return propertyList[id]['campaign_id'];
	}
	
	var currentLocationQuery = '';
	
	var propertyList = {};
	
	var activeIds = [];

}
