/**
 * var config = { baseUrl : "/Community", startIndex : 1, pageSize : 12 };
 */
HD.CommunityDAO = function(config) {
	this.config = config || {};

	// {boolean/string} secure: Converts KickApps URL's to
	// https://www.harley-davidson.com/ redirect (or custom URL if specified).
	this.config.secure = this.config.secure || false;
	if (this.config.secure && typeof this.config.secure == 'boolean') {
		this.config.secure = 'https://www.harley-davidson.com/';
	}

	this.mediaBaseUrl = 'http://media.kickstatic.com/';
	this.mediaUrlFields = [ 'thumbUrl', 'url' ];
	this.pageNumber = config.startIndex;
	this.initialPageIndex = config.startIndex;
	this.totalPages = config.startIndex;
	this.totalMedia = 0;
	this.activeItem = null;
	this.filters = config.filters || {};
	this.activeItemIndexOnPage = 0;
	this.activeItemPage = config.startIndex;
	this.observers = [];
	this.ratings = [];

	if (!!this.config.restoreState) {
		this.restoreState(typeof this.config.restoreState == 'string' ? this.config.restoreState : null, true);
	}
};

HD.CommunityDAO.prototype = {
	getMedia : function(pageNumber, isLastIndexActive, preventSetActiveItem,
			setThisIndex) {

		this.notifyObservers("getMedia_Start");

		this.pageIndex = pageNumber;

		var mediaRequest = {
			pageNumber : pageNumber
		};

		this.setFilters(mediaRequest);

		var cb = this;
		var isLastCb = isLastIndexActive;
		var preventSetActiveItem = preventSetActiveItem || false;

		var callMetadata = {
			callback : function(mediaResponse) {

				var eventName = mediaResponse.success ? "getMedia_Finish"
						: "getMedia_Error";

				var media = mediaResponse.media;

				var filteredMedia = [];

				var prevMedium = null;
				for ( var i = 0, len = media.length; i < len; i++) {
					var medium = media[i];
					if (medium != null) {
						if (prevMedium != null) {
							medium.previous = prevMedium;
						}
						if (i < len - 1) {
							medium.next = media[i + 1];
						}

						cb.setFacade.call(cb, medium);

						filteredMedia.push(medium);
					}
					prevMedium = medium;
				}

				var activeIndex = setThisIndex
						|| (isLastCb ? media.length - 1 : 0);

				// TODO
				if (filteredMedia.length > 0 && !preventSetActiveItem) {
					cb.activeItem = filteredMedia[activeIndex];
				}

				cb.totalPages = mediaResponse.totalPages;
				cb.pageNumber = mediaResponse.pageNumber;
				cb.totalMedia = mediaResponse.totalMedia;

				cb.media = filteredMedia;

				mediaResponse.media = filteredMedia;
				cb.notifyObservers.call(cb, eventName, mediaResponse);

				if (filteredMedia.length > 0) {
					// !!! do not remove this,
					// otherwise 'activeItem_Change' event won't fire
					var itemToSetActive = filteredMedia[activeIndex];

					if (!preventSetActiveItem) {
						cb.activeItem = null;
						cb.setActiveItem.call(cb, itemToSetActive);
					}
				}
			},
			parameters : {
				siteName : this.config.siteName
			}
		};

		if (this.config.preloadedMedia == null) {
			CommunityService.getMedia(mediaRequest, callMetadata);
		} else {
			callMetadata.callback(this.config.preloadedMedia.getMedia());
			this.config.preloadedMedia = null;
		}
	},

	// Convert URL's to secure URL's if needed.
	applySecureUrl : function(medium) {
		if (this.config.secure) {
			for ( var i = 0; i < this.mediaUrlFields.length; i++) {
				var field = [ this.mediaUrlFields[i] ];
				if (medium[field]) {
					medium[field] = medium[field].replace(this.mediaBaseUrl,
							this.config.secure);
				}
			}
		}
		return medium;
	},

	hasNextPage : function() {
		return this.pageNumber < this.totalPages;
	},

	hasPreviousPage : function() {
		return this.pageNumber > this.initialPageIndex;
	},

	getNextPage : function(preventSetActiveItem) {
		if (this.hasNextPage()) {
			this.getMedia(++this.pageNumber, null, preventSetActiveItem);
		}
	},

	getSamePage : function() {
		this.getMedia(this.pageNumber);
	},

	getPreviousPage : function(isLastIndexActive, preventSetActiveItem) {
		if (this.hasPreviousPage()) {
			this.getMedia(--this.pageNumber, isLastIndexActive,
					preventSetActiveItem);
		}
	},

	getActiveItem : function() {
		return this.activeItem;
	},

	hasNextItem : function() {
		if (this.activeItem && this.activeItem.next != null) {
			return true;
		}
		return this.hasNextPage();
	},

	hasPreviousItem : function() {
		if (this.activeItem && this.activeItem.previous != null) {
			return true;
		}
		return this.hasPreviousPage();
	},

	getNextItem : function() {
		if (this.activeItem.next != null) {
			this.setActiveItem(this.activeItem.next);
		} else if (this.hasNextPage()) {
			this.getNextPage();
			this.notifyObservers("activeItem_PageChange");
		}
	},

	getPreviousItem : function() {
		if (this.activeItem.previous != null) {
			this.setActiveItem(this.activeItem.previous);
		} else if (this.hasPreviousPage()) {
			this.getPreviousPage(true);
			this.notifyObservers("activeItem_PageChange");
		}
	},

	setActiveItem : function(item) {

		if (this.activeItem != null && this.activeItem.mediaId == item.mediaId) {
			return;
		}
		this.activeItem = item;
		this.notifyObservers("activeItem_Change", item);
	},

	setFacade : function(medium) {
		if (medium != null) {
			// Apply secure URL if necessary.
			this.applySecureUrl(medium);

			// Extract meta tags.
			var isMetaTag = /^hd:([a-zA-Z0-9_]+?)(=(.+))?$/;
			if (medium.tags && medium.tags.length > 0) {
				medium.metaTags = {};
				for ( var i = medium.tags.length - 1; i >= 0; i--) {
					var metaTag = medium.tags[i].match(isMetaTag);
					if (metaTag) {
						medium.tags.splice(i, 1);
						medium.metaTags[metaTag[1]] = metaTag[3] || true;
					}
				}
			}

			if (HD.community.isBlog(medium.contentType)) {
				medium.facade = new HD.community.Blog(medium);
			} else if (HD.community.isPhoto(medium.contentType)) {
				medium.facade = new HD.community.Photo(medium);
			} else if (HD.community.isVideo(medium.contentType)) {
				medium.facade = new HD.community.Video(medium);
			}
		}
	},

	getMedium : function(mediaId, callback, contentType) {
		this.notifyObservers("getMedium_Start");
		var mediaRequest = {
			mediaId : mediaId
		};

		this.setFilters(mediaRequest);

		if (contentType != null) {
			mediaRequest.contentType = contentType;
		}

		var cb = this;
		var cbCb = callback;

		var callMetadata = {
			callback : function(mediaResponse) {
				var media = mediaResponse.media;
				var eventName = mediaResponse.success ? "getMedium_Finish"
						: "getMedium_Error";
				var medium = media[0];
				cb.setFacade.call(cb, medium);

				cb.insertItem.call(cb, medium);

				if (cbCb != null) {
					cbCb(medium);
				}

				cb.addCachedMedium.call(cb, medium);

				cb.setActiveItem.call(cb, medium);
				cb.notifyObservers.call(cb, eventName, medium);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};

		CommunityService.getMedium(mediaRequest, callMetadata);
	},
	
	getMultipleMedium : function(mediaIds, callback, contentType) {
		this.notifyObservers("getMultipleMedium_Start");
		var mediaRequest = { mediaId: (mediaIds || []).join(','), contentType: contentType || this.config.contentType }; 

		this.setFilters(mediaRequest);

		if (contentType != null) {
			mediaRequest.contentType = contentType;
		}

		var cb = this;
		var cbCb = callback;

		var callMetadata = {
			callback : function(mediaResponse) {
				var media = mediaResponse.media;
				var eventName = mediaResponse.success ? "getMultipleMedium_Finish" : "getMultipleMedium_Error";
				
				for (var i = 0; i < media.length; i++) {
					cb.setFacade.call(cb, media[i]);
					cb.insertItem.call(cb, media[i]);
					cb.addCachedMedium.call(cb, media[i]);
				}

				if (!!cbCb) {
					cbCb(media);
				}
				
				cb.notifyObservers.call(cb, eventName, media);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};

		CommunityService.getMultipleMedium(mediaRequest, callMetadata);
	},

	getTags : function(itemsLimit) {
		this.notifyObservers("getTags_Start");

		var mediaRequest = {
			itemsLimit : itemsLimit
		};

		this.setFilters(mediaRequest);
		// Using tags with this call results in bad data coming back.
		if (mediaRequest.tags) {
			delete mediaRequest.tags;
		}

		var cb = this;

		var callMetadata = {
			callback : function(mediaResponse) {
				var eventName = mediaResponse.success ? "getTags_Finish"
						: "getTags_Error";

				// Remove meta tags.
				var isMetaTag = /^hd:([a-zA-Z0-9_]+?)(=(.+))?$/;
				for ( var i = mediaResponse.tags.length - 1; i >= 0; i--) {
					if (mediaResponse.tags[i].tagName.match(isMetaTag)) {
						mediaResponse.tags.splice(i, 1);
					}
				}

				cb.notifyObservers.call(cb, eventName, mediaResponse);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};

		CommunityService.getTags(mediaRequest, callMetadata);
	},

	getMonthly : function(itemsLimit) {
		this.notifyObservers("getMonthly_Start");

		var mediaRequest = {
			itemsLimit : itemsLimit
		};

		this.setFilters(mediaRequest);

		var cb = this;

		var callMetadata = {
			callback : function(mediaResponse) {
				var eventName = mediaResponse.success ? "getMonthly_Finish"
						: "getMonthly_Error";
				cb.notifyObservers.call(cb, eventName, mediaResponse);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};

		CommunityService.getMonthly(mediaRequest, callMetadata);
	},

	getAllBlogAuthors : function(itemsLimit) {
		this.notifyObservers("getAllBlogAuthors_Start");

		var mediaRequest = {
			itemsLimit : itemsLimit
		};

		this.setFilters(mediaRequest);
		var cb = this;

		var callMetadata = {
			callback : function(mediaResponse) {
				var eventName = "getAllBlogAuthors_Finish";
				cb.notifyObservers.call(cb, eventName, mediaResponse);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};

		CommunityService.getAllBlogAuthors(callMetadata);
	},

	getFacebookEvents : function() {
		this.notifyObservers("getFacebookEvents_Start");

		var cb = this;

		var callMetadata = {
			callback : function(mediaResponse) {
				// var eventName = mediaResponse.success ? "getFBEvents_Finish"
				// : "getFBEvents_Error";
			var eventName = "getFacebookEvents_Finish";
			cb.notifyObservers.call(cb, eventName, mediaResponse);
		},
		parameters : {
			siteName : this.config.siteName
		}
		};

		CommunityService.getAllFacebookEvents(callMetadata);
	},
	
	getFutureFacebookEvents : function() {
		this.notifyObservers("getFutureFacebookEvents_Start");

		var cb = this;

		var callMetadata = {
			callback : function(mediaResponse) {
				// var eventName = mediaResponse.success ? "getFBEvents_Finish"
				// : "getFBEvents_Error";
			var eventName = "getFutureFacebookEvents_Finish";
			cb.notifyObservers.call(cb, eventName, mediaResponse);
		},
		parameters : {
			siteName : this.config.siteName
		}
		};

		CommunityService.getFutureFacebookEvents(callMetadata);
	},

	getAllFacebookAttendeesForEvent : function(eventId, limit) {
		this.notifyObservers("getFacebookAttendeesForEvent_Start");

		var cb = this;

		var callMetadata = {
			callback : function(mediaResponse) {
			//var eventName = mediaResponse.success ? "getFacebookAttendeesForEvent_Finish" : "getFacebookAttendeesForEvent_Error";
			var eventName = "getFacebookAttendeesForEvent_Finish";
			cb.notifyObservers.call(cb, eventName, mediaResponse);
		},
		parameters : {
			siteName : this.config.siteName
		}
		};

		CommunityService.getAllFacebookAttendeesForEvent(eventId, limit, callMetadata);
	},

	getYoutubeMedia : function(numberToReturn) {
		this.notifyObservers("getYoutube_Start");

		var youtubeRequest = {
			numberToReturn : numberToReturn
		};

		// this.setFilters(youtubeRequest);

		var cb = this;

		var callMetadata = {
			callback : function(mediaResponse) {
				var eventName = "getYoutube_Finish";
				cb.notifyObservers.call(cb, eventName, mediaResponse);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};
		CommunityService.getYoutubeMedia(youtubeRequest, callMetadata);
	},

	getTwitterFeed : function() {
		this.notifyObservers("getTwitterFeed_Start");

		var cb = this;

		var callMetadata = {
			callback : function(mediaResponse) {
				var eventName = "getTwitterFeed_Finish";
				cb.notifyObservers.call(cb, eventName, mediaResponse);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};

		CommunityService.getTwitterFeed(callMetadata);
	},

	getPopular : function(itemsLimit, sortType) {
		this.notifyObservers("getPopular_Start");

		var mediaRequest = {
			itemsLimit : itemsLimit
		};

		this.setFilters(mediaRequest);
		// if sort type wasn't passed in, default to highest rated
		if (!HD.util.Common.hasValue(sortType)) {
			sortType = HD.SORTS.HIGHEST_RATED;
		}

		mediaRequest.sortType = sortType;

		var cb = this;

		var callMetadata = {
			callback : function(mediaResponse) {
				var eventName = mediaResponse.success ? "getPopular_Finish"
						: "getPopular_Error";

				var media = mediaResponse.media;

				var prevMedium = null;
				for ( var i = 0, len = media.length; i < len; i++) {
					var medium = media[i];
					if (medium != null) {
						if (prevMedium != null) {
							medium.previous = prevMedium;
						}
						if (i < len - 1) {
							medium.next = media[i + 1];
						}
					}
					cb.setFacade.call(cb, medium);
					prevMedium = medium;
				}

				mediaResponse.media = media;

				cb.notifyObservers.call(cb, eventName, mediaResponse);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};

		CommunityService.getPopularMedia(mediaRequest, callMetadata);
	},

	getComments : function(mediaId, contentType) {

		this.notifyObservers("getComments_Start");
		var mediaRequest = {
			mediaId : mediaId
		};

		this.setFilters(mediaRequest);

		if (HD.util.Common.hasValue(contentType)) {
			mediaRequest.contentType = contentType;
		}

		var cb = this;

		var callMetadata = {
			callback : function(mediaResponse) {
				var eventName = mediaResponse.success ? "getComments_Finish"
						: "getComments_Error";
				var media = mediaResponse.media;				
				var medium = media[0];
				var comments = medium.comments;
				
				// Replace the anonymous submitter label
				for (var i=0; i<comments.length; i++){
					var submitter = comments[i].submittedBy;
					if (submitter.match(/^anonymoususer/i)){
				
						comments[i].submittedBy = 'anonymous';
					}
				}
				
				
				// TODO insert into cache setting previous and next
				cb.notifyObservers.call(cb, eventName, medium);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};
		CommunityService.getComments(mediaRequest, callMetadata);
	},
	
	// getFaceoff aggregates getComments(getMedium) and getMedium calls.
	getFaceoff : function(mediaId) {
		this.notifyObservers("getFaceoff_Start");
		this.notifyObservers("getComments_Start");
		var cb = this;
		var request = { mediaId: mediaId };
		this.setFilters(request);
		
		// Use the back-end implementation of getFaceoff if available.
		var metadata = {
			callback : function(response) {
				// Set media facades.
				if (response.success) {
					cb.setFacade(response.faceoff);
					for (var i = 0; i < response.media.length; i++) {
						cb.setFacade(response.media[i]);	
					}
				}
				
				var eventName = response.success ? "_Finish" : "_Error";
				cb.notifyObservers('getComments' + eventName, response.faceoff || null);
				cb.notifyObservers('getFaceoff' + eventName, response);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};
		CommunityService.getFaceoff(request, metadata);
	},
	
	/**
	 * "formId" or HTML Form element
	 */
	submitMedium : function(form) {
		this.notifyObservers("submitMedium_Start");
		var type = "";
		var formEl = form;

		if (form.type.value != null && form.type.value != "") {
			type = "?type=" + form.type.value;
		}

		var cb = this;

		HD.util.Common.uploadFile(
						form,
						this.config.baseUrl + "/fileUpload" + type,
						function(uploadResponse) {
							var eventName = (uploadResponse.indexOf("success") >= 0) ? "submitMedium_Finish"
									: "submitMedium_Error";
							var eventData = new Array(4);
							eventData[0] = uploadResponse;
							eventData[1] = formEl.title.value;
							eventData[2] = formEl.story.value;
							eventData[3] = formEl.type.value || '';
							clearTimeout(HD.UploadWidget.progressTimer);
							cb.notifyObservers.call(cb, eventName, eventData);
						});
	},

	submitComment : function(mediaId, contentType, comment) {
		this.notifyObservers("submitComment_Start", comment);

		var mediaRequest = {
			mediaId : mediaId,
			comment : comment,
			contentType : contentType
		};

		this.setFilters(mediaRequest);
		var cb = this;

		var callMetadata = {
			callback : function(mediaResponse) {
				var eventName = mediaResponse.success ? "submitComment_Finish"
						: "submitComment_Error";
				var response = null;
				if (mediaResponse.success) {
					// TODO insert into cache setting previous and next
					response = mediaResponse.media[0];
					cb.setFacade.call(cb, response);
				} else {
					response = mediaResponse.errors;
				}

				HD.util.Analytics.track(cb.analyticsCommentString.call(cb,
						response));

				cb.notifyObservers.call(cb, eventName, response);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};

		CommunityService.submitComment(mediaRequest, callMetadata);
	},

	rateMedia : function(mediaId, contentType, rating) {
		this.notifyObservers("rateMedia_Start");

		var mediaRequest = {
			mediaId : mediaId,
			rating : rating,
			contentType : contentType
		};

		this.setFilters(mediaRequest);
		var cb = this;

		var callMetadata = {
			callback : function(mediaResponse) {
				var eventName = mediaResponse.success
						&& mediaResponse.media != null ? "rateMedia_Finish"
						: "rateMedia_Error";

				var medium = null;
				var media = mediaResponse.media;
				if (media != null) {
					medium = media[0];

					cb.setFacade.call(cb, medium);
					cb.insertItem.call(cb, medium);

					cb.addCachedMedium.call(cb, medium);

					HD.util.Analytics.track(cb.analyticsRatingString.call(cb,
							medium));
				}

				// TODO insert into cache setting previous and next
				cb.notifyObservers.call(cb, eventName, medium);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};
		CommunityService.rateMedia(mediaRequest, callMetadata);
	},

	insertItem : function(medium) {
		var cachedMedia = this.media;
		if (cachedMedia != null) {
			for ( var i = 0, len = cachedMedia.length; i < len; i++) {
				if (cachedMedia[i] != null
						&& cachedMedia[i].mediaId == medium.mediaId) {
					// delete cachedMedia[i];
					if (i > 0) {
						medium.previous = cachedMedia[i - 1];
					}
					if (i < len - 1) {
						medium.next = cachedMedia[i + 1];
					}
					cachedMedia[i] = medium;
				}
			}
		}
		this.media = cachedMedia;
	},

	getMemberProfile : function(memberId) {
		this.notifyObservers("getMember_Start");

		var profileRequest = {
			memberId : memberId
		};

		this.setFilters(profileRequest);

		var cb = this;

		var callMetadata = {
			callback : function(memberResponse) {
				var profile = memberResponse.profile;
				var eventName = memberResponse.success ? "getMember_Finish"
						: "getMember_Error";

				cb.notifyObservers.call(cb, eventName, profile);
			},
			parameters : {
				siteName : this.config.siteName
			}
		};

		CommunityService.getMemberProfile(profileRequest, callMetadata);
	},

	getRatings : function(media) {
		this.notifyObservers("getRatings_Start");

		// if no media explicitly passed in, assume user wants to get
		// ratings for current media items
		if (media == null) {
			media = this.media;
		}

		var siteName = this.config.siteName;
		var ratings = [];
		for ( var i = 0, len = media.length; i < len; i++) {
			var medium = media[i];
			ratings.push( {
				mediaId : medium.mediaId,
				contentType : medium.contentType,
				siteName : siteName
			});
		}

		var ratingRequest = {
			ratings : ratings
		};

		this.setFilters(ratingRequest);

		var cb = this;
		var mediaCb = media;

		var callMetadata = {
			callback : function(ratingResponse) {
				var eventName = ratingResponse.success ? "getRatings_Finish"
						: "getRatings_Error";

				var ratings = ratingResponse.ratings;
				var media = mediaCb;

				for ( var i = 0, len = media.length; i < len; i++) {
					var medium = media[i];
					var rating = ratings[i];

					if (medium != null && rating != null) {
						medium.currentUserRating = rating.rating;
						cb.addCachedMedium(medium);
						medium.facade.updateRatingWidgets(medium);
					}
				}
			},
			parameters : {
				siteName : this.config.siteName
			}
		};

		CommunityService.getRatings(ratingRequest, callMetadata);
	},

	getCachedMedium : function(mediaId) {
		var medium = this.ratings[mediaId];

		if (medium == null && this.media != null) {
			var media = this.media;
			for ( var i = 0, len = media.length; i < len; i++) {
				var mediumTemp = media[i];
				if (mediumTemp != null && mediumTemp.mediaId == mediaId) {
					medium = mediumTemp;
					break;
				}
			}
		}

		return medium;
	},

	addCachedMedium : function(medium) {
		this.ratings[medium.mediaId] = medium;
	},

	setFilters : function(request) {
		var filters = this.filters;
		var config = this.config;

		request.siteName = config.siteName;

		if (filters.startDate != null) {
			request.startDate = filters.startDate;
		}
		if (filters.endDate != null) {
			request.endDate = filters.endDate;
		}
		if (filters.sortType != null) {
			request.sortType = filters.sortType;
		}
		if (filters.tags != null) {
			request.tags = filters.tags;
		}
		if (filters.members != null) {
			request.members = filters.members;
		}
		if (filters.metaTags != null) {
			request.tags = (request.tags || []).concat(filters.metaTags);
		}
		if (filters.author != null) {
			request.author = filters.author;
		}
		if (filters.contentSubtype != null) {
			request.contentSubtype = filters.contentSubtype;
		}
		if (filters.numberToReturn != null) {// newksl: youtube related
			request.numberToReturn = filters.numberToReturn;
		}
		if (config.categories != null) {
			request.categories = config.categories;
		}
		if (config.contentType != null && request.contentType == null) {
			request.contentType = config.contentType;
		}
		if (config.pageSize != null) {
			request.pageSize = config.pageSize;
		}
		if (config.thumbWidth != null) {
			request.thumbWidth = config.thumbWidth;
		}
		if (config.mediaWidth != null) {
			request.mediaWidth = config.mediaWidth;
		}

	},

	setDateRange : function(dateRange, skipUpdate, setActive) {
		this.notifyObservers("dateRange_Set", dateRange);
		this.filters.startDate = dateRange.startDate;
		this.filters.endDate = dateRange.endDate;
		if (!skipUpdate) {
			this.getMedia(1, null, !setActive);
		}
	},

	clearDateRange : function(skipUpdate, setActive) {
		this.notifyObservers("dateRange_Clear");
		delete this.filters.startDate;
		delete this.filters.endDate;
		if (!skipUpdate) {
			this.getMedia(1, null, !setActive);
		}
	},

	setMetaTags : function(tags, skipUpdate, setActive) {
		this.filters.metaTags = typeof tags == 'string' ? [ tags ] : tags;
		if (this.filters.metaTags.length == 0) {
			return this.clearMetaTags(skipUpdate);
		}
		this.notifyObservers("metaTags_Set", this.filters.metaTags);
		if (!skipUpdate) {
			this.getMedia(1, null, !setActive);
		}
	},

	clearMetaTags : function(skipUpdate, setActive) {
		delete this.filters.metaTags;
		this.notifyObservers("metaTags_Clear", []);
		if (!skipUpdate) {
			this.getMedia(1, null, !setActive);
		}
	},

	setTags : function(tags, skipUpdate, setActive) {
		this.filters.tags = typeof tags == 'string' ? [ tags ] : tags;
		if (this.filters.tags.length == 0) {
			return this.clearTags(skipUpdate);
		}
		this.notifyObservers("tags_Set", this.filters.tags);
		if (!skipUpdate) {
			this.getMedia(1, null, !setActive);
		}
	},

	clearTags : function(skipUpdate, setActive) {
		delete this.filters.tags;
		this.notifyObservers("tags_Clear", []);
		if (!skipUpdate) {
			this.getMedia(1, null, !setActive);
		}
	},

	setAuthor : function(author, skipUpdate, setActive) {
	
		this.filters.author = author.userName;
		if (this.filters.author.length == 0) {
			return this.clearAuthor(skipUpdate);
		}
		this.notifyObservers("author_Set", author);
		if (!skipUpdate) {
			this.getMedia(1, null, !setActive);
		}
	},

	clearAuthor : function(skipUpdate, setActive) {
		delete this.filters.author;
		this.notifyObservers("author_Clear", []);
		if (!skipUpdate) {
			this.getMedia(1, null, !setActive);
		}
	},

	setContentSubtype : function(contentSubtype, skipUpdate, setActive) {
		this.filters.contentSubtype = contentSubtype;
		if (this.filters.contentSubtype.length == 0) {
			return this.clearContentSubtype(skipUpdate);
		}
		this.notifyObservers("contentSubtype_Set", this.filters.contentSubtype);
		if (!skipUpdate) {
			this.getMedia(1, null, !setActive);
		}
	},

	clearContentSubtype : function(skipUpdate, setActive) {
		delete this.filters.contentSubtype;
		this.notifyObservers("contentSubtype_Clear", []);
		if (!skipUpdate) {
			this.getMedia(1, null, !setActive);
		}
	},

	setCategories : function(categories, skipUpdate, setActive) {
		this.config.categories = categories.slice(0);
		this.notifyObservers("categories_Set", categories);
		if (!skipUpdate) {
			this.getMedia(1, null, !setActive);
		}
	},

	setSort : function(sortType) {
		this.notifyObservers("sortType_Change", sortType);
		this.filters.sortType = sortType;
		this.pageNumber = this.initialPageIndex;
		this.getSamePage();
	},

	getSort : function(sortType) {
		return this.filters.sortType;
	},

	isInCurrentPage : function(itemId) {
		var itemExistsInPage = false;
		var media = this.media;

		for ( var i = 0; i < media.length; i++) {

			if (media[i].mediaId == itemId) {

				itemExistsInPage = true;
				break;
			}

		}
		return itemExistsInPage;
	},

	_generateState : function() {
		// Only include properties that are valid.
		var state = {
			categories : this.config.categories.join(';')
		};
		if (this.filters.tags) {
			state.tags = this.filters.tags.join(';');
		}
		if (this.filters.members) {
			state.members = this.filters.members.join(';');
		}
		if (this.filters.author) {
			state.author = this.filters.author.join(';');
		}
		if (this.filters.contentSubtype) {
			state.contentSubtype = this.filters.contentSubtype.join(';');
		}
		if (this.filters.startDate) {
			state.startDate = this.filters.startDate;
		}
		if (this.filters.endDate) {
			state.startDate = this.filters.startDate;
		}
		if (this.filters.sortType) {
			state.sortType = this.filters.sortType;
		}
		return state;
	},

	_applyState : function(state, skipUpdate) {
		if (!state) {
			return false;
		}
		if (typeof state == 'string') {
			state = YAHOO.util.Cookie._parseCookieHash(state);
		}
		if (state.categories) {
			this.setCategories(state.categories.split(';'), true);
		}
		if (state.tags) {
			this.setTags(state.tags.split(';'), true);
		}
		if (state.author) {
			this.setAuthor(state.author);
		}
		if (state.contentSubtype) {
			this.setContentSubtype(state.contentSubtype);
		}
		if (state.startDate) {
			this.filters.startDate = state.startDate;
		}
		if (state.endDate) {
			this.filters.endDate = state.endDate;
		}
		if (state.sortType) {
			this.filters.sortType = state.sortType;
		}
		if (!skipUpdate) {
			this.getMedia(1);
		}
		return true;
	},

	// Manage state using strings.
	exportState : function() {
		return YAHOO.util.Cookie._createCookieHashString(this._generateState());
	},
	importState : function(stateString, skipUpdate) {
		return this._applyState(stateString, skipUpdate);
	},

	// Manage state using cookies.
	storeState : function(name) {
		return YAHOO.util.Cookie.setSubs(name || this.config.siteName, this
				._generateState());
	},
	restoreState : function(name, skipUpdate) {
		return this._applyState(YAHOO.util.Cookie.getSubs(name
				|| this.config.siteName), skipUpdate);
	},
	clearState : function(name) {
		return YAHOO.util.Cookie.remove(name || this.config.siteName);
	},

	analyticsRatingString : function(item) {
		return "default_analyticsRatingString";
	},

	analyticsCommentString : function(item) {
		return "default_analyticsCommentString";
	}
};

HD.extend(HD.CommunityDAO, [ HD.util.Observable ]);

HD.register('hd_community_model', 'HD.CommunityDAO', {
	version : "1.0",
	build : "1"
});