var Tabs = function() {
	return {
		init : function(tabs_id) {
			var tabContainers = $(tabs_id + ' > div.tab');
			tabContainers.hide();
		
			$('div.tabs ul.tab-nav li a').live('click', function () {
				
				var cur_nav = $(this); 
				var ul = $(this).parents("ul.tab-nav");
				var wrapper = ul.parent();
				var tabs = $(this).parents("div.tabs"); //a -> li -> ul -> tab divs
				var tabContainers = $('div.tab', tabs);
				
				if (cur_nav.hasClass('selected')) {
					//collpase it 
					tabContainers.hide();					
					cur_nav.removeClass('selected'); 
					ul.removeClass('selected');					
					wrapper.removeClass('wrapper-selected');					
				}else {
					tabContainers.hide();
					tabContainers.filter(this.hash).show();
				
					$('ul.tab-nav li a', tabs).removeClass('selected');
					cur_nav.addClass('selected');
					ul.addClass('selected');
					wrapper.addClass('wrapper-selected');
					//trigger tab show event
					cur_nav.trigger('tabsshow');
				}
				
				return false;				
			});
		}
	}
}();
var GeoUtil = function (){
	var geocoder = null; 
	var get_geocoder = function() {
		if (!geocoder) {
			geocoder = new google.maps.Geocoder();	
		}
		return geocoder;
	};
	return {
		suggest : function(latlng, locale, complete_callback) {
			if (latlng) {
	          	get_geocoder().geocode({'latLng': latlng, 'language': locale}, 
				function(results, status) {
					var places = [];
			        if (status == google.maps.GeocoderStatus.OK) {

						if (results.length > 0) {

							var addr_len = results.length; 
							for (var k=0; k<addr_len; k++) {
								var address = results[k];
								var components = address.address_components;
								var len = components.length;
								for (var i=0; i<len; i++) {
									var skip = false;
									for (var j=0; j<components[i].types.length; j++) {
										if (components[i].types[j] == "street_number" ||
											components[i].types[j] == "route" || 
											components[i].types[j] == "postal_code"){
											skip = true;
											break;
										}
									}
									if (!skip && $.inArray(components[i].long_name, places) == -1) {
										places.push(components[i].long_name);									
									}
								}	
							}
						}
			        }
					//save the places to photo 								
					complete_callback(places);
				});					
			}
		}
	}
}();
var MNTableView = function () {
	
	var _ds_controller = null; 	
	var _delegate = null; 
	
	var _commands = [];
	var _container = null;
	var _cell_menu = null;
	var _cell_menu_edit = null;
	var _cell_menu_del = null;	
	var _settings = null;
	
	var _selected_index = -1;	
	

	var	on_edit_cell = function(e)
	{	
		if (_delegate.edit_cell != null) {

			var item = _ds_controller.get_data(_selected_index_path) ;
			var cell = group_list().eq(_selected_index_path[0]).find("DIV.cell").eq(_selected_index_path[1]);
			_delegate.edit_cell(_selected_index_path, item, cell);		
		}
	};
	
	//obsolete to be removed
	var on_command = function(e) {
		fn = e.data; 
		var cell = $(e.target).parents("div.cell"); 			

		var row_index = cell_list().index(cell);
		selected_index = row_index;		
		var item = _datasource[row_index];
		fn(item, row_index, cell);
	}; 
	
	var on_delete_cell = function(e) {

		if (_delegate.delete_cell != null){
			
			var item = _ds_controller.get_data(_selected_index_path) ;
			var cell = group_list().eq(_selected_index_path[0]).find("DIV.cell").eq(_selected_index_path[1]);
			_delegate.delete_cell(_selected_index_path, item, cell);
		}
	};
		
	var render_cell = function(index_path, item, cell) {

		if (_delegate.render_view_cell != null)	{	
			_delegate.render_view_cell(index_path, item, cell);
		}
	};
	
	var render_section = function(index, item, section) {
		if (_delegate.render_view_section != null)	{	
			_delegate.render_view_section(index, item, section);										
		}
	};
	
	var render_header = function(container) {
		if (_delegate.render_header != null)	{	
			var header = $('<div class="header"></div>').appendTo(container);
			_delegate.render_header(header);										
		}
	};

	var render_footer = function(container) {
		if (_delegate.render_footer != null)	{	
			var footer = $('<div class="footer"></div>').appendTo(container);			
			_delegate.render_footer(footer);										
		}
	};
	
	var _get_index_path = function(cell) {
		//look for the group object 
		var group = cell.parent();
				
		var section_index = group_list().index(group);
		var cell_index = $("DIV.cell", group).index(cell);	
		var index_path = [section_index, cell_index]; 	
		return index_path;
	};
	
	var on_mouseover_cell = function(e) {

		var cell = $(this); 
		_selected_index_path = _get_index_path(cell)
		var cell_menu = $("div.cell-menu" ,cell); 
					
		var pos = cell.offset();  		
	  	var width =  cell_menu.width();

		//cell_menu.css({ "left": (pos.left) + "px", "top":pos.top + "px" }); 
		//cell_menu.css({ "left": "0px", "top":"11px" }); 
		cell_menu.show();
	};	
	
	var on_mouseout_cell = function(e) {

		var cell = $(this); 
		$("div.cell-menu" ,cell).hide();
	};
	
	var gen_cell = function() {
		var cell = $('<div class="cell"></div>');	
		return cell;
	};
	
	var gen_section = function() {
		var section = $('<div class="section"></div>');	
		return section;
	};
	
	var gen_group = function() {
		var group = $('<div class="group"></div>'); 
		return group;
	}; 
	
	var group_list = function() {
		return $("DIV.group", _container);
	};
	
	
	return {
		
		init : function(container, settings) {
			_container = container;
			_settings = settings;
			
			if (_settings['editable'] == true) {
				$("div.cell", _container).live('mouseover', on_mouseover_cell);
				$("div.cell", _container).live('mouseout', on_mouseout_cell);
			
				$("div.cell-menu a.edit").live('click', on_edit_cell);
				$("div.cell-menu a.delete").live('click', on_delete_cell);			
			}
		},
		
		get_container : function() {
			return _container;
		},
		
		set_datasource_controller: function(ds_controller) {
			
			_ds_controller = ds_controller; 			
		},
		
		get_index_path: function(cell) {
			return _get_index_path(cell);
		},
		
		add_command: function(command) {
			_commands.push(command);
		},	
		set_delegate: function(del){
			_delegate = del;
		},
		
		clear: function() {
			_container.empty();		
		},
						
		render: function() {
			

			_container.empty();		
			//header 
			render_header(_container);

			var len = _ds_controller.get_len(null); 	

			for (var i=0; i<len; i++){
				

				var group = gen_group(); 


				if (_delegate.render_view_section != null)	{
					var sec_item = _ds_controller.get_data([i]); 						
					var sec = gen_section();
					group.append(sec);
					render_section(i, sec_item, sec); 
				}
				

				if (_delegate.render_view_cell != null)	{

					var len_cell = _ds_controller.get_len([i]); 	
					for (var k=0; k<len_cell; k++){
						var cell = 	gen_cell();	

						var index_path = [i,k];
						var sub_item = _ds_controller.get_data(index_path)					

						render_cell(index_path, sub_item, cell);				
						group.append(cell);						
					}
				}

				_container.append(group);
			}

			//footer
			render_footer(_container);
		},
		
		/* Manipulate functions
		*************************************************/		
		create_section: function(index) {
						
			var sec_item = _ds_controller.get_data([index]); 	
			var group = gen_group(); 
			var sec = gen_section();
			group.append(sec); 
			
			render_section(index, sec_item, sec);
			
			var len = group_list().length;
			if (len == 0) {
				//there is no section before
				_container.append(group);
			}else if (index > len - 1){
				// insert after the last element
				//TESTED
				group.insertAfter(group_list().eq(len -1));
			}else {
				//TESTED
				group.insertBefore(group_list().eq(index));		
			}
		},
		
		delete_section: function(index) {
			group_list().eq(index).remove();
		},
		
		update_section: function(index) {
			//TESTED
			var sec_item = _ds_controller.get_data([index]); 	
			var group = group_list().eq(index);
			var sec = $("DIV.section", group);
			sec.empty(); 
			if (sec_item)
				render_section(index, sec_item, sec);
		},
		
		get_section: function(index) {
			var section = group_list().eq(index); 
			return section;
		},
		
		get_cell: function(index_path) {
			var cell = group_list().eq(index_path[0]).find("DIV.cell").eq(index_path[1]);
			return cell;
		},
	
		delete_cell: function(index_path) {
			
			var old_cell = group_list().eq(index_path[0]).find("DIV.cell").eq(index_path[1]);
			old_cell.remove(); 
		},
		
		update_cell: function(index_path, new_index_path){
		
			var new_cell = gen_cell();				

			//look up the old cell 
			var old_cell = group_list().eq(index_path[0]).find("DIV.cell").eq(index_path[1]);
			
			//remove the old cell
			old_cell.remove();
					
			//insert it to the position
			var cells = group_list().eq(new_index_path[0]).find("DIV.cell");
			
			var len = cells.length;				
			if (len == 0 || new_index_path[1] > len - 1){
				// appned as first or to the last element
				var group = group_list().eq(new_index_path[0]); 
				group.append(new_cell);
			}else {
				var group = group_list().eq(new_index_path[0]); 
				new_cell.insertBefore(group.find("DIV.cell").eq(new_index_path[1]));
			}			
	
			var item = _ds_controller.get_data(new_index_path);				
			render_cell(new_index_path, item, new_cell); 										
		},
		
		create_cell: function(index_path) {
			
			var new_cell = gen_cell();
			var item = _ds_controller.get_data(index_path);				
			
			//insert it to the position
			var section_index = index_path[0];			
			var item_index = index_path[1];
			
			var group = group_list().eq(section_index);
			var cells = $("DIV.cell", group);

			var len = cells.length;
			if (len == 0) {
				//TESTED
				//there is no cell before
				if (group.length == 0) {
					var group = gen_group(); 
					group.append(new_cell); 
					_container.append(group);
				}else {
					group.append(new_cell);					
				}

			}else if (item_index > len - 1){
				//TESTED
				// insert after the last element
				new_cell.insertAfter(cells.eq(len -1));
			}else {
				//TESTED
				new_cell.insertBefore(cells.eq(item_index));		
			}
			
			render_cell(index_path, item, new_cell); 															
		}
	};
};
var TripGridController = function() {

	// helper classes
	var _grid = null; 
	var _datasource = null; 
	var _userid = null;

	//ui controlls
	var _btn_more = null; 
	var _dialog = null; 
	
	var _params = {}; 
	
	var _next_bookmark = null; 
	
	var load_more = function() {
		_datasource.fetch(_next_bookmark, MOVNOTE.fetchLimit.trip, _params);
	};
	
	var show_delete_trip = function() {

		var cell = $(this).parents("div.cell"); 
		var index_path = _grid.get_index_path(cell); 

		_dialog.dialog('option', 'buttons', {
				Delete: function() {
					var item = _datasource.get_data(index_path);
					_datasource.del_item(index_path, {"tripid":item.tripid});
				},
				Cancel: function() {
					$(this).dialog('close');
				}
			}
		);
		_dialog.dialog('open');
	};
		
	return {
		
		/* DataSource Controller  Delegate function
		*************************************************/
		deleted_data : function(index_path) {

			_grid.delete_cell(index_path);			
			_dialog.dialog('close');
		},
							
		loaded_data : function(index_path, prev, next) {
			if (next) {
				_next_bookmark = next;
				_btn_more.show();
			}else {
				_btn_more.hide();
			}
			
			//it was empty
			if (index_path[0] == 0 && index_path[1] == 0) {
				_grid.render();		
			}else {
				var len = _datasource.get_len([0]);
				for (var i=index_path[1] + 1; i<len; i++) {
					_grid.create_cell([0,i])
				}
			}
		},
		
		/* Grid Delegate function
		*************************************************/				
		render_view_cell : function(index_path, item, cell) {

			var shadow = $('<div class="cell-shadow"></div>').appendTo(cell); 
			
			var div = $('<div class="image"></div>').appendTo(shadow); 
			
			if (item.cover_thumb_m) {
				$('<a href="/trip/' + item.tripid + '/1"><img class="thumb" src="' + item.cover_thumb_m + '" /></a>').appendTo(div);
			}else {
				$('<a href="/trip/' + item.tripid + '/1"><img class="thumb" src="/images/trip-nopic.png" /></a>').appendTo(div);				
			}

			
			var title_div = $('<div class="title"></div>').appendTo(div); 
			if (item.title)
				$('<span class="title"></span>').text(item.title).appendTo(title_div);			
			$('<p class="title">&nbsp;</p>').appendTo(div);
						
			if (item.like_count > 0) {
				$('<span class="count">&nbsp;</span>').appendTo(div);
				if (item.like_count > 1) {
					$('<span class="count">' + item.like_count + ' ' + MNUtil.trans("likes") + '</span>').appendTo(title_div); 
				}else{
					$('<span class="count">' + item.like_count + ' ' + MNUtil.trans("like") + '</span>').appendTo(title_div); 
				}
			}
			
			if (item.bookmark_count > 0) {
				$('<span class="count">&nbsp;</span>').appendTo(div);		
				if (item.bookmark_count > 1) {
					$('<span class="count">' + item.bookmark_count + ' ' + MNUtil.trans("bookmarks") + '</span>').appendTo(title_div); 
				}else{
					$('<span class="count">' + item.bookmark_count + ' ' + MNUtil.trans("bookmark") + '</span>').appendTo(title_div); 
				}
			}			
			if (item.created_by)
				$('<a class="creator" href="/profile/' + item.created_by + '">' + item.created_by_name + '</a>').appendTo(title_div);						
			$('<p class="title">&nbsp;</p>').appendTo(div);				
			

			$(['<div style="display:none;" class="cell-menu"><a class="edit" href="/upload?tripid=' + item.tripid + '"></a><a class="delete"></a></div>']).appendTo(cell);

			
		},
		
		init : function(trip_grid, datasource, container, userid, params, del_panel) {
			
			if (params) _params = params;
			_userid = userid;			
			_grid = trip_grid;
			_datasource = datasource;
			_grid.set_datasource_controller(datasource);
			
			$('a.delete', trip_grid.get_container()).live("click", show_delete_trip);
			

			if (_userid) {
				_params["userid"] = _userid; 
			}	
			_datasource.fetch(null, MOVNOTE.fetchLimit.trip, _params); 
			
			_btn_more = $("a.btn-more", container);
			_btn_more.click(load_more);
			
			if (!del_panel) {
				del_panel = $("#panel-trip-del");
			} 
						
			_dialog = del_panel.dialog({
				resizable: false,
				height:200,
				width:400,
				modal: true,
				autoOpen: false
			});
		}	
	};
}; 

var NoteGridController = function() {

	// helper classes
	var _grid = null; 
	var _datasource = null; 
	var _userid = null;

	//ui controlls
	var _btn_more = null; 
	var _dialog = null; 
	
	var _params = {}; 
	
	var _next_bookmark = null; 
	
	var load_more = function() {
		_datasource.fetch(_next_bookmark, MOVNOTE.fetchLimit.trip, _params);
	};
	
	var show_delete_trip = function() {

		var cell = $(this).parents("div.cell"); 
		var index_path = _grid.get_index_path(cell); 

		_dialog.dialog('option', 'buttons', {
				Delete: function() {
					var item = _datasource.get_data(index_path);
					_datasource.del_item(index_path, {"tripid":item.tripid});
				},
				Cancel: function() {
					$(this).dialog('close');
				}
			}
		);
		_dialog.dialog('open');
	};
		
	return {
		
		/* DataSource Controller  Delegate function
		*************************************************/
		deleted_data : function(index_path) {

			_grid.delete_cell(index_path);			
			_dialog.dialog('close');
		},
							
		loaded_data : function(index_path, prev, next) {
			if (next) {
				_next_bookmark = next;
				_btn_more.show();
			}else {
				_btn_more.hide();
			}
			
			//it was empty
			if (index_path[0] == 0 && index_path[1] == 0) {
				_grid.render();		
			}else {
				var len = _datasource.get_len([0]);
				for (var i=index_path[1] + 1; i<len; i++) {
					_grid.create_cell([0,i])
				}
			}
		},
		
		/* Grid Delegate function
		*************************************************/				
		render_view_cell : function(index_path, item, cell) {

			var shadow = $('<div class="cell-shadow"></div>').appendTo(cell); 
			
			var div = $('<div class="image"></div>').appendTo(shadow); 
			
			if (item.thumb_m) {
				$('<a href="/note/' + item.noteid + '"><img class="thumb" src="' + item.thumb_m + '" /></a>').appendTo(div);
			}else {
				$('<a href="/note/' + item.noteid + '"><img class="thumb" src="/images/trip-nopic.png" /></a>').appendTo(div);				
			}

			
			var title_div = $('<div class="title"></div>').appendTo(div); 
			if (item.title)
				$('<span class="title"></span>').text(item.title).appendTo(title_div);			
			$('<p class="title">&nbsp;</p>').appendTo(div);
						
			if (item.like_count > 0) {
				$('<span class="count">&nbsp;</span>').appendTo(div);
				if (item.like_count > 1) {
					$('<span class="count">' + item.like_count + ' ' + MNUtil.trans("likes") + '</span>').appendTo(title_div); 
				}else{
					$('<span class="count">' + item.like_count + ' ' + MNUtil.trans("like") + '</span>').appendTo(title_div); 
				}
			}
			
			if (item.bookmark_count > 0) {
				$('<span class="count">&nbsp;</span>').appendTo(div);		
				if (item.bookmark_count > 1) {
					$('<span class="count">' + item.bookmark_count + ' ' + MNUtil.trans("bookmarks") + '</span>').appendTo(title_div); 
				}else{
					$('<span class="count">' + item.bookmark_count + ' ' + MNUtil.trans("bookmark") + '</span>').appendTo(title_div); 
				}
			}			
			if (item.created_by)
				$('<a class="creator" href="/profile/' + item.created_by + '">' + item.created_by_name + '</a>').appendTo(title_div);						
			$('<p class="title">&nbsp;</p>').appendTo(div);				
			
		},
		
		init : function(note_grid, datasource, container, userid, params) {
			
			if (params) _params = params;
			_userid = userid;			
			_grid = note_grid;
			_datasource = datasource;
			_grid.set_datasource_controller(datasource);
			

			if (_userid) {
				_params["userid"] = _userid; 
			}	
			_datasource.fetch(null, MOVNOTE.fetchLimit.note, _params); 
			
			_btn_more = $("a.btn-more", container);
			_btn_more.click(load_more);			
		}	
	};
}; 

var DataSourceController = function ()
{
	var _results = []; 
	var _delegates = []; 
	var _entity = null; 
	var _errors = {};
	
	/* Fetch note 
	*************************************************/
	
	var load_data_callback = function(data) {
		
		var next = data.next; 
		var prev = data.prev;
		
		var results = data.results;
		var len = results.length;		
		
		var index = _results.length; 
					
		var index_path = [0, index]; 
		
		for (var i=0; i<len; i++){
			var item = results[i]; 
			_results.push(item);				
		}		
	
		//run delegates
		var len = _delegates.length;
		for (var i=0; i<len; i++) {
			var del = _delegates[i];
			if (del.loaded_data != null) {
				del.loaded_data(index_path, prev, next);
			}
		}
	}; 
	
	var load_data_error = function(error){
		ErrorHandler.show(_errors["LoadError"] + error.msg);
	};
	
	var delete_data_callback = function(data, obj) {
		var index_path = obj;
		var len = _delegates.length;
		
		_results.splice(index_path[1], 1);
		
		for (var i=0; i<len; i++) {
			var del = _delegates[i];
			if (del.deleted_data != null)
				del.deleted_data(index_path);
		}
	};
	
	var delete_data_error = function(error) {
		ErrorHandler.show(_errors["DeleteError"] + error.msg);
	};
	
	return {
		clear: function() {
			_results = [];
		},
		
		add_delegate : function(del) {
			_delegates.push(del);
		},
		
		del_item : function(index_path, params) {

			var request = MNRequest();
			request.init(_entity, index_path);
			request.del(delete_data_callback, delete_data_error, params);
		},
		
		/* Data Source Controller methods
		**********************************************/
		get_len : function(index_path) {
			if (index_path == null)
				return 1;
			else if (index_path.length == 1)
				return _results.length;
		},

		get_data : function(index_path) {			
			return _results[index_path[1]];			
		},
		
		fetch: function(cursor, limit, params) {

			if (!params) {
				params = {}; 
			}
			
			if (limit) {
				params["limit"] = limit;					
			}
			
			if (cursor) {
				params["cursor"] = cursor;										
			}
			
			request = MNRequest(); 
			request.init(_entity);
			
			request.get(load_data_callback,
						load_data_error,
						params);
		},
		
		set_errors : function(errors) {
			_errors = errors;
		},
					
		init : function(entity) {
			_entity = entity;
		}
	}; 
};

var WordListController = function() {

	// helper classes
	var _datasource = null; 
	var _grid = null;

	//ui controlls
	var _btn_more = null; 
	var _next_bookmark = null; 
	var _params = null;
	var _userid = null; 

	var load_more = function() {
		_datasource.fetch(_next_bookmark, 5, _params);
	};
	
	return {
		
		/* DataSource Controller  Delegate function
		*************************************************/
		loaded_data : function(index_path, prev, next) {
			if (next) {
				_next_bookmark = next;
				_btn_more.show();
			}else {
				_btn_more.hide();
			}
			
			//it was empty
			if (index_path[0] == 0 && index_path[1] == 0) {
				_grid.render();		
			}else {
				var len = _datasource.get_len([0]);
				for (var i=index_path[1]; i<len; i++) {
					_grid.create_cell([0,i])
				}
			}
		},
		
		/* Grid Delegate function
		*************************************************/				
		render_view_cell : function(index_path, item, cell) {

			var div = $('<div class="word"></div>').appendTo(cell);
			
			var link = $('<a class="text">' + item.title + '</a>').appendTo(div);
			var del = $('<a class="delete"></a>').appendTo(div);
			
			link.click(function(){
				var link = $(this).text()
				$("#search-text").val(link); 
				if (_userid) {
					$("#search-userid").val(_userid); 
				}
				$("#search-form").submit();
			})
		},
		
		init : function(grid, datasource, container, params, userid) {
		
			_userid = userid;
			_grid = grid;
			_params = params;
			_grid.set_datasource_controller(datasource);
			
			_datasource = datasource;
			_datasource.fetch(null, 5, params); 
			
			_btn_more = $("a.btn-more", container);
			_btn_more.click(load_more);
		}	
	};
};
;(function($) {

	$.extend($.fn, {
		
		finish_edit: function() {
			var panel = $(this).parent(); 
			panel.hide(); 
			
			var container = panel.parent(); 
			$("a.edit", container).show();
			$("span.editable-text", container).text($("input", container).val());
			$("span.editable-text", container).show();
		},
		
		
		
		editable: function(settings) {
			
			var save_fn = settings.save; 
			var div = $(this); 
			
			var edit_btn = $('<a class="thin-button edit"><span>' + MNUtil.trans("Edit") +'</span></a>').appendTo(div);
			$('<div style="clear:both;">').appendTo(div);
			
			var edit = $('<div class="editable-panel" style="display:none"></div>')
			$('<input type="text" class="editable-input-text" />').appendTo(edit);
			var save_btn = $('<a class="thin-button save"></a>').appendTo(edit);
			$('<span>Save</span>').appendTo(save_btn);
			var cancel_btn = $('<a class="thin-button cancel"><span>Cancel</span></a>').appendTo(edit);
			$('<div style="clear:both;"></div>').appendTo(edit);
			edit.appendTo(div); 
			
			if (save_fn) {
				save_btn.click(save_fn); 
			}
			
			edit_btn.click(function() {
				$(this).hide()
				var container = $(this).parent(); 
				$("input.editable-input-text", container).val($("span.editable-text", container).text()); 
				$("span.editable-text", container).hide();
				$("div.editable-panel", container).show();
			})
			
			cancel_btn.click(function() {
				var edit_panel = $(this).parent(); 
				edit_panel.hide();
				
				var container = edit.parent();
				$("input", container).val($("span.editable-text", container).text()); 
				$("span.editable-text", container).show();				
				$("a.edit", container).show();
			})
		}
	});
	
})(jQuery);

