/*
Copyright (c) 2009, Geomatics and Cartographic Research Centre, Carleton 
University. All rights reserved.

Redistribution and use in source and binary forms, with or without 
modification, are permitted provided that the following conditions are met:

 - Redistributions of source code must retain the above copyright notice, 
   this list of conditions and the following disclaimer.
 - Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
 - Neither the name of the Geomatics and Cartographic Research Centre, 
   Carleton University nor the names of its contributors may be used to 
   endorse or promote products derived from this software without specific 
   prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
POSSIBILITY OF SUCH DAMAGE.

$Id: olkit_PlaceInfo.js 5264 2010-01-27 01:50:34Z glennbrauen $
*/

/*
 * manage user contributions (comments, audio, and video contributions)
 * associated with a place.
 * Media contributions use the db key as the object identifer in the repository
 */
var _olkit_clickedPlaceInfo = null;
function _olkit_pi_mediaClick(key, path) {
	if (null == _olkit_clickedPlaceInfo) {
		return;
	};
	var contrib = _olkit_clickedPlaceInfo.getContribution(key);
	if (null == contrib) {
		return;
	};
	
	// Figure out if it is an image
	var isImage = (function(){
		var filename = contrib.filename;
		if (null == filename || "" == filename ||
			null == contrib.mimetype || "" == contrib.mimetype) {
			return false;
		};
		
		var mimeClass = contrib.mimetype.split("/");
		var type = mimeClass[0];
	
		if (type === "image") {
			return true;
		};
		return false;	
	})();
	
	if( isImage ) {
		var lightBoxOptions = {
			imageLocation: 'olkit-jslib/jquery.lightbox.resources/'
		};
		
		var title = '';
		if( contrib.title ) {
			title += contrib.title;
		};
		if( contrib.contributor && contrib.contributor.display ) {
			title += ' (by ' + contrib.contributor.display+')';
		};
		if( contrib.notes ) {
			title += ' <br />' + contrib.notes;
		};
		
		var imagePath = path+contrib.filename;
		$.lightBox(lightBoxOptions,[{href:imagePath,title:title}]);
		
	} else {
		$("#modal_overlay").html(_olkit_getMediaEmbeddingMarkup(contrib, path, true));
		$("#mediaViewer").jqmShow();
	};
};

function _olkit_getMediaEmbeddingMarkup(contrib, path, showCaption) {	
	var filename = contrib.filename;
	if (null == filename || "" == filename ||
		null == contrib.mimetype || "" == contrib.mimetype) {
		return "";
	}
	
	var mimeClass = contrib.mimetype.split("/");
	var type = mimeClass[0];
	var caption = contrib.notes;
	var title = contrib.title;

	var htmlString = '<div>';
	if (null != title && "" != title) {
		htmlString += '<p>'+title+'</p>'
	}
	
	if (type === "image") {
		htmlString += '<p><img src="'+path+filename+'" alt="'+(caption || "an image")+'"/></p></div>';
	} else if (type === "video") {
		htmlString += '<p><OBJECT classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="320"'+
							'height="256" codebase="http://www.apple.com/qtactivex/qtplugin.cab">'+
							'<param name="src" value="'+path+filename+'">'+
							'<param name="autoplay" value="false">'+
							'<param name="controller" value="true"><param name="loop" value="false">'+
							'<EMBED src="'+path+filename+'" width="320" height="256" '+
							'autoplay="false" controller="true" loop="false" '+
							'pluginspage="http://www.apple.com/quicktime/download/"></EMBED></OBJECT></p></div>';
	} else if (type === "audio") {
		htmlString += '<p><OBJECT classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="320" '+
							'height="16" codebase="http://www.apple.com/qtactivex/qtplugin.cab">'+
							'<param name="src" value="'+path+filename+'">'+
							'<param name="autoplay" value="false"><param name="controller" value="true">'+
							'<param name="loop" value="false"><EMBED src="'+path+filename+'" '+
							'width="320" height="16" autoplay="false" controller="true" loop="false" '+
							'pluginspage="http://www.apple.com/quicktime/download/"></EMBED></OBJECT></p></div>';
	}
	
	if (true == showCaption && null != caption && "" != caption) {
		htmlString += '<p>'+caption+'</p>'
	}
	return(htmlString);
}

function _olkit_contributionAddClick(placeId, relatedTo) {
	if( $.NUNALIIT_AUTH ) {
		// The auth module is present, check if user logged in
		if( $.NUNALIIT_AUTH.getUser() ) {
			if( NUNALIIT_CONTRIBUTIONS ) {
				var dataObj = {
						place_id: placeId
					};
				if (relatedTo) {
					dataObj.related_to = relatedTo;
				}
				NUNALIIT_CONTRIBUTIONS.acceptsContribution({ data : dataObj });
			} else {
				alert("Contribution module not installed.");
			};
		} else {
			// User is not logged in
			$.NUNALIIT_AUTH.login({
				onSuccess:function(){
					_olkit_contributionAddClick(placeId, relatedTo);
					}
				,anonymousLoginAllowed: true
			});
		};
	} else {
		alert("Authentication module not installed.");
	};
}

function _olkit_contributionUpdateClick(contributionId) {
	if (null == _olkit_clickedPlaceInfo) {
		return;
	};
	var contrib = _olkit_clickedPlaceInfo.getContribution(contributionId);
	if (null == contrib) {
		return;
	};
	
	if ($.NUNALIIT_AUTH) { // The auth module is present
		var dataObj = $.extend({}, contrib); // copy contribution fields
		var allowed = false;
		if (null != contrib.contributor) {
			allowed = $.NUNALIIT_AUTH.isUpdateAllowed(contrib.contributor.display);
		} else {
			// allows admin updating, even if no contributor info stored with contribution
			allowed = $.NUNALIIT_AUTH.isUpdateAllowed('');
		}
		if (allowed) {
			if (NUNALIIT_CONTRIBUTIONS) {
				NUNALIIT_CONTRIBUTIONS.acceptsContributionUpdate({ data: dataObj });
			} else {
				alert("Contribution module not installed.");
			};
		} else { // User is not logged in appropriately
			$.NUNALIIT_AUTH.login({
				onSuccess:function(){
					_olkit_contributionDeleteClick(contributionId, placeId);
					}
				,anonymousLoginAllowed: false
				,prompt: 'Please login.'
			});
		};
	} else {
		alert("Authentication module not installed.");
	};
};

function _olkit_contributionDeleteClick(contributionId, placeId) {
	if( $.NUNALIIT_AUTH ) {
		// The auth module is present, check if user is admin
		var allowed = $.NUNALIIT_AUTH.isDeleteAllowed();
		if (allowed) {
			if( NUNALIIT_CONTRIBUTIONS ) {
				if( confirm('Are you sure you want to delete this contribution?') ) {
					var options = {
							data: {
								id: contributionId
								,placeId: placeId
							}
							,onSuccess: onSuccess
							,onError: onError
						};
					NUNALIIT_CONTRIBUTIONS.deleteContribution(options);
				};
			} else {
				alert("Contribution module not installed.");
			};
		} else {
			// User is not logged in as admin
			$.NUNALIIT_AUTH.login({
				onSuccess:function(){
					_olkit_contributionDeleteClick(contributionId, placeId);
					}
				,anonymousLoginAllowed: false
				,prompt: 'Please login with administrative credentials'
			});
		};
	} else {
		alert("Authentication module not installed.");
	};
	
	function onSuccess(msg, textStatus) {
	};
	function onError(xmlHttpRequest, textStatus, errorThrown) {
		alert('Error occurred while deleting a contribution. You might need to refresh your page.');
	};
};

function olkit_PlaceInfo(initialFeature_, options_, dbSearchEngine_, contributionDb_) {
	var feature = initialFeature_;
	var repository = {};
	var dbSearchEngine = dbSearchEngine_;
	var contributionDb = contributionDb_;
	
	var options = {
		displayDiv               : null
		,attribTableHeading      : "Place Data:" // display heading for place attributes.
		,attribTableDiv          : null       /* place attribute div - created dynamically */
		,attribTableClassBase    : "attrib"   /* modified as needed to create columns - see olkit_PlaceInfo */
		,contribTableHeading     : "Contributions:" // display heading for contributions.
		,contribTableDiv         : null       /* contributions table div - created dynamically */
		,contribTableClassBase   : "contrib" /* modified as needed to create columns */
		,contribTableRespLinks   : true // show the respond links on the contributions table.
		,contribTableShowAuthor  : true // show the author on each contribution?
		,contributionAddClick    : _olkit_contributionAddClick
		,contributionDeleteClick : _olkit_contributionDeleteClick
		,contributionUpdateClick : _olkit_contributionUpdateClick
		,contribMediaClick       : _olkit_pi_mediaClick
	};
	
    $.extend(options, options_);
    
    if (null === options.displayDiv || null === options.contribTableDiv || null === options.attribTableDiv) {
    	alert("olkit_PlaceInfo - displayDiv OR contribTableDiv OR attribTableDiv not specified.");
    	return;
    }
    var ddiv = document.getElementById(options.displayDiv);
    if (null === ddiv) {
    	alert("olkit_PlaceInfo - displayDiv ("+options.displayDiv+") not found.");
    	return;
    }
	
	function initContribDisplay() {
		$("#"+options.displayDiv).empty();
	    
		var workingHtml =
	    	'<div id="'+options.attribTableDiv+'">'+
	    	'<p><table class="'+options.attribTableClassBase+'_header">'+
			'<tr class="'+options.attribTableClassBase+'_header">'+
			'<td>' + options.attribTableHeading + '</td></tr></table></p><p><table>';
	    for (var i in feature.attributes) {
			if (feature.attributes.hasOwnProperty(i) &&
				feature.attributes[i] !== null) {
				workingHtml += '<tr><td class="label">'+i+
					': </td><td class="info">'+feature.attributes[i]+'</td></tr>';
			}
		}
		workingHtml += '</table></p></div><div id="'+options.contribTableDiv+'"> </div>';
		
	 	$("#"+options.displayDiv).html(workingHtml);
	}
	initContribDisplay(); // do initial display
 	
 	var NULL_RELATED_TO = -1;
 	function indexContributions(repository) {
 	 	var rRelatedOrder = null;
 		var inserted = 0;
 		var skippedSome = false;
 		
 	 	var index = [];
		rRelatedOrder = {};
 		
 		// the logic here assumes that all contributions with related_to != 0
 		// are related to contributions that have the same place_id.  Otherwise
 		// they're not in this list.
 		//
 		// grab all repository entries with related_to = null
 		for (var m in repository) {
 			if (repository.hasOwnProperty(m)) {
 				if (null == repository[m].related_to ||
 					0 == repository[m].related_to) {
 					index.push({
 							order         : inserted,
 							key           : m,
 							related_to    : NULL_RELATED_TO,
 							related_order : NULL_RELATED_TO
 						});
 					rRelatedOrder[m] = inserted;
 					inserted += 1;
 				} else {
 					skippedSome = true;
 				}
 			}
 		}
 		
 		if (!skippedSome) { // catches case of no contributions and case of no related contributions
 			return index;
 		}
 		
 		// now grab all of the entries with related_to != null
 		for (var m in repository) {
 			if (repository.hasOwnProperty(m)) {
 				if (null != repository[m].related_to &&
 					0 != repository[m].related_to) {
 					index.push({
 							order         : inserted,
 							key           : m,
 							related_to    : (rRelatedOrder.hasOwnProperty(repository[m].related_to) ?
 												repository[m].related_to : NULL_RELATED_TO),
 							related_order : (rRelatedOrder.hasOwnProperty(repository[m].related_to) ?
 												rRelatedOrder[repository[m].related_to] : NULL_RELATED_TO)
 						});
 					inserted += 1;
 				}
 			}
 		}
 		
 		index.sort(function(a,b) {
 				if (NULL_RELATED_TO == a.related_to && NULL_RELATED_TO == b.related_to) {
 					return(a.order - b.order);
 				} else if (NULL_RELATED_TO == a.related_to && NULL_RELATED_TO != b.related_to) {
 					if (a.key == b.related_to) {
 						return(-1); // related after original
 					} else {
 						return(a.order - b.related_order);
 					}
 				} else if (NULL_RELATED_TO != a.related_to && NULL_RELATED_TO == b.related_to) {
 					if (a.related_to == b.key) {
 						return(1); // related after original
 					} else {
 						return(a.related_order - b.order);
 					}
 				} else { // (NULL_RELATED_TO != a.related_to && NULL_RELATED_TO != b.related_to) 
 					if (a.related_to == b.related_to) {
 						return(a.order - b.order);
 					} else {
 						return(a.related_order - b.related_order);
 					}
 				}
 			});

 		return index;
 	};
 	
 	var cdf = null;
	function renderContributions() {
		var index = indexContributions(repository);
		if (null == cdf) {
			cdf = olkit_ContDisplayFormatter({
					contribTableClassBase     : options.contribTableClassBase
					,contributionAddClick     : options.contributionAddClick
					,contributionDeleteClick  : options.contributionDeleteClick
					,contributionUpdateClick  : options.contributionUpdateClick
					,contribMediaClick        : options.contribMediaClick
					,showRespondLink          : options.contribTableRespLinks
					,showContribAuthor        : options.contribTableShowAuthor
				}
				,dbSearchEngine
			);
		}
		
		var headElem = $('<p></p>');
		{
			var headTable = $('<table class="'+options.contribTableClassBase+'_header"></table>');
			headElem.append(headTable);
			
			var headTr = $('<tr class="'+options.contribTableClassBase+'_header"><td width="50%">'+options.contribTableHeading+'</td></tr>');
			headTable.append(headTr);
			
			var headTd = $('<td align="center"></td>');
			headTr.append(headTd);
			
			var headButton = $('<input type="button" value="Add yours!"></input>');
			headButton.click(function(){
				options.contributionAddClick(feature.attributes.place_id, null);
			});
			headTd.append(headButton);
		}
		
		var contribElem = null;
		if (0 == index.length) {
			contribElem = $('<p><table><tr><td>There are currently no contributions.</td></tr></table></p>');
		} else {
			contribElem = $('<p></p>');
			
			var table = $('<table class="'+options.contribTableClassBase+'"></table>');
			contribElem.append(table);
			
			for (var i=0; i<index.length; i++) {
				var parms = { key : index[i].key };

				if (i < index.length-1) {
					// not last element
					if (NULL_RELATED_TO != index[i].related_to) {
						// current is related to earlier
						if (NULL_RELATED_TO != index[i+1].related_to) {
							// next is also related to earlier - continueRelatedSet
							parms.rowType = cdf.getExtensionType_contRelated();
							var trElem = cdf.formatAsTR(repository[parms.key], parms, ((index.length-1) == i));
							table.append(trElem);
						} else {
							// next is not related to earlier - endRelatedSet
							parms.rowType = cdf.getExtensionType_endRelated();
							var trElem = cdf.formatAsTR(repository[parms.key], parms, ((index.length-1) == i));
							table.append(trElem);
						};
					} else {
						// current not related to earlier
						if (NULL_RELATED_TO != index[i+1].related_to) {
							// next is related to current - startRelatedSet
							parms.rowType = cdf.getExtensionType_startRelated();
							var trElem = cdf.formatAsTR(repository[parms.key], parms, ((index.length-1) == i));
							table.append(trElem);
						} else {
							// next is not related to current - basic contribution
							parms.rowType = cdf.getExtensionType_basic();
							var trElem = cdf.formatAsTR(repository[parms.key], parms, ((index.length-1) == i));
							table.append(trElem);
						};
					};
				} else {
					// last element
					if (NULL_RELATED_TO != index[i].related_to) {
						// current is related to earlier - endRelatedSet
						parms.rowType = cdf.getExtensionType_endRelated();
						var trElem = cdf.formatAsTR(repository[parms.key], parms, ((index.length-1) == i));
						table.append(trElem);
					} else {
						// current is not related to earlier - basic contribution
						parms.rowType = cdf.getExtensionType_basic();
						var trElem = cdf.formatAsTR(repository[parms.key], parms, ((index.length-1) == i));
						table.append(trElem);
					};
				};
			};
		};
		
		$("#"+options.contribTableDiv)
			.empty()
			.append(headElem)
			.append(contribElem)
			;
	}
	
	return {
		setFeatureReinitDisplay : function(newFeature) {
				feature = newFeature;
				repository = {}; // empty repository
				initContribDisplay();
			},

		reinitDisplay : function() {
				initContribDisplay();
				renderContributions();
			},
			
		getPlaceId : function() {
				return (feature.attributes.place_id);
			},
			
		getFid : function() {
				return (feature.fid);
			},
			
		loadAndRenderContributions : function() {
				if( feature.attributes.place_id ) {
					contributionDb.getContributionsFromPlaceId(feature.attributes.place_id,function(contributions){
						repository = {};
						$.each(contributions, function(i, contribution) {
								repository[contribution.id] = contribution;
								return(true);
							});
						renderContributions();
					});
				}
			},
						
		getContribution : function(key) {
				return(repository[key]);
			},
	};
}
