(function($){
	$(document).ready(function(){
		var currentLayout, sectionCount = [];

		function initPage(){
			//reset form
			$('#sitebuilder-editpagetemplate-form').trigger('reset');
			$('#btnAdd').attr('disabled', 'disabled'); //form reset doesn't reset disabled state

			//transform screen layout radio buttons to thumbnails
			$('#layout_list input[type=radio]').thumbnailRadioCheckbox({
				thumbnailClass:'radio-checkbox-thumbnail layout-border',
				select:function($thumbnail, $radio){
					$('.canvas-layout').removeClass('show').addClass('hide');
					$('#canvas-' + $radio.attr('id')).removeClass('hide').addClass('show');
					selectLayout('canvas-' + $radio.attr('id'));
				}
			});

			//transform widget checkboxes to thumbnails
			$('#widget-list input[type=checkbox]').thumbnailRadioCheckbox({
				thumbnailClass:'radio-checkbox-thumbnail widget-border shadow',
				select:function($thumbnail, $checkbox){
					$thumbnail.css({'border-style':'inset', 'border-color':'#FFF'});
					$thumbnail.parent().removeClass('shadow');
					$('#btnAdd').removeAttr('disabled');
				},
				unselect:function($thumbnail, $checkbox){
					$thumbnail.css({'border-style':'solid', 'border-color':'transparent'});
					$thumbnail.parent().addClass('shadow');
					if ($('#widget-list input[type=checkbox]:checked').length == 0){
						$('#btnAdd').attr('disabled', 'disabled');
					}
				}
			});

			//populate the corresponding displaysections[] hidden textbox with the added widgets when Save button is clicked
			$('#btnSave').click(function(){
				for (var i=0; i<sectionCount[currentLayout]; i++) {
					var arr = [];
					$('#' + currentLayout + ' > div.section-' + i +' > div.canvas-widget').each(function(index){
						arr.push($(this).attr('widget-id') + '=' + ($(this).attr('widget-instance-id')||'0'));
					});
					$('#' + currentLayout + ' input[name="displaysections[' + i + ']"]').val(arr.join(','));
				}

				//@todo:temporary only
				//location.href = 'page';
				//return false;

				// @todo: Consider doing some AJAX form validation here?

				return true;

			});
			//Cancel Edit Page Template
			$('#btnCancel').click(function(){
				location.href = $(this).attr('data-cancel-url');
			});
			//Preview Edit Page Template
			$('#btnPreview').click(function(){
				//@todo
				alert('Not implemented yet. (5)');
			});

			//add widget button
			$('#btnAdd').click(function(){

				$(this).attr('disabled', 'disabled');

				var widgets = [];
				$('#widget-list .widget-border.selected').each(function(){
					widgets.push({
					    widgetid: $(this).parent().parent().attr('id').replace(/widget_/, ''),
					    widgetinstanceid: 0
					});
				});
				addWidgets(widgets, true);

			});

			//widget close button click
			$('.canvas-widget .canvas-widget-item .close-button').live('click', function(){
				$('#confirm-dialog').data('confirm-mode', 'deletewidget');

				//remember which item to remove
				$('#confirm-dialog').data('widget-draggable-item', $(this).parent().parent());

				$('#confirm-dialog').dialog('option', 'title', 'Remove Widget?');
				$('#confirm-dialog .dialog-content').html('<p>Do you really want to remove the <strong>{0}</strong> widget?</p><p>Warning! This action cannot be undone.</p>'.format($(this).prev().text()));
				$('#confirm-dialog').dialog('open');
			});

			//channel widget close button click
			$('.channel-list .channel-item .close-button').live('click', function(){
				$('#confirm-dialog').data('confirm-mode', 'deletechannel');

				//remember which item to remove
				$('#confirm-dialog').data('widget-draggable-item', $(this).parent().parent());

				var $parentChannelContainer = $(this).parent().parent().parent();
				var channelText = ($parentChannelContainer.hasClass('main-channel-container')) ? 'Channel' : 'Sub-Channel';
				$('#confirm-dialog').dialog('option', 'title', 'Remove {0}?'.format(channelText));
				$('#confirm-dialog .dialog-content').html('<p>Do you really want to remove the <strong>{0}</strong> {1}?</p><p>Warning! This action cannot be undone.</p>'.format($(this).prev().text(), channelText));
				$('#confirm-dialog').dialog('open');
			});

			//channel widget Edit button click
			$('.channel-widget .canvas-widget-item .edit-button').live('click', function(){
				var $widgetContainer = $(this).parent().parent();
				$('#channel-config-dialog').data('channel-widget', $(this).closest('.channel-widget')); //remember corresponding channel widget
				$('#channel-config-dialog').dialog('open');
				return false;
			});

			//make page canvas widget items draggable-n-droppable
			$('.canvas-widget-list, .unassigned-widget-list').sortable({
				connectWith: ".connectedSortable",
				placeholder: "canvas-widget-highlight round-corner5 clear",
				update: function(event, ui){
					$('.unassigned-widget-list:not(:hidden) > div.clear').appendTo($('.unassigned-widget-list'));
					ui.item.css('z-index', '0'); //for IE7
					adjustDivider();
				},
				sort:function(event, ui){
					ui.item.addClass('shadow');
					adjustDivider();
				},
				start:function(event, ui){
					ui.item.removeClass('shadow');
					if ($.browser.msie && parseInt($.browser.version, 10) == 8){ //IE8 widget height is bigger
						ui.item.height(ui.item.height()-4);
					}
					ui.item.css('z-index', '99999'); //for IE7
					ui.placeholder.height(ui.item.height());
				},
				handle:'.canvas-widget-item > .grip-icon',
				items:'.canvas-widget'
			});

			//get column counts for each layout
			$('.canvas-layout-container .canvas-layout').each(function(){
				sectionCount[this.id] = $('#' + this.id + ' div[class*="section-"]').length;
			});

			//add channel button
			$('.add-channel-fieldset .add-btn').live('click', function(){
				var $channelTitleField = $(this).prev();
				var channelTitle = $.trim($channelTitleField.val());
				if (channelTitle != $channelTitleField.attr('defaultValue')){
					addChannel('', channelTitle);

					//reset channel title field
					$channelTitleField.val('').focus();
				}
				else {
					initErrorDialog(null, function(){
						$channelTitleField.focus();
					});
					showErrorDialog('<span>Please enter Channel Title.</span>');
				}

			});

			//channel title click handler
			$('.main-channel-container .channel-item .channel-title div').live('click', function(){
				$(this).hide();
				var $channelTitle = $(this).next();
				$channelTitle.show();
				$channelTitle.select();
				$channelTitle.focus();
			});

			//channel title textbox blur handler
			$('.main-channel-container .channel-item .channel-title input').live('blur', function(){
				$(this).hide();
				$(this).prev().html($(this).val());
				$(this).prev().show();
			});

			//initialize widget config dialog
			$('#config-dialog').dialog({
				title:'Widget Configuration',
				autoOpen:false,
				modal:true,
				resizable:false,
				closeOnEscape:false,
				height:500,
				width:800,
				dialogClass:'sb-dialog-container config-dialog-container shadow-dark',
				create:function(){
					//submit form handler to save config
					$('#sitebuilder-widget-form').submit(function() {

			  		  $('body').css('cursor', 'wait');
			  		  $('#config-dialog .action-buttons button').attr('disabled', 'disabled');

					  $.ajax({
				  			url:this.action,
				  			type:this.method,
				  			data:($(this).serializeArray()),
				  			dataType: 'json',
				  			success:function(result){
				  				$('body').css('cursor', 'auto');

				  				//@todo:check for validation errors returned by the server here

				  				$('#config-dialog').dialog('close');
				  			},
				  			error:function(xhr, statusText, error){
				  				$('body').css('cursor', 'auto');
				  				initErrorDialog(null, function(){
				  					$('#config-dialog .action-buttons button').removeAttr('disabled');
								});
								showErrorDialog('<span>Error saving the configuration for "' + $('#config-dialog .widget-name h1').text() + '" widget.<br /><br />Please try again later.</span>');
								$('#config-dialog .widget-loader').hide();
				  			}
				  		});

					  	return false;
					});
					$('#btnCloseConfig').click(function(){
						$('#config-dialog').dialog('close');
					});
				},
				close:function(){
					$('#config-dialog .action-buttons button').removeAttr('disabled');
				}
			});

			//initialize channel widget config dialog
			$('#channel-config-dialog').dialog({
				title:'Edit Channel Module',
				autoOpen:false,
				modal:true,
				resizable:false,
				closeOnEscape:false,
				//height:500,
				width:700,
				dialogClass:'sb-dialog-container channel-config-dialog-container shadow-dark',
				open:function(){
					//add existing channels
					$('.widget-channel-list > li', $('#channel-config-dialog').data('channel-widget')).each(function(){
						var $channel = addChannel($(this).attr('data-channel-id'), $('>span', this).html());
						$('.widget-subchannel-list > li', this).each(function(){
							addSubChannel($(this).attr('data-channel-id'), $('>span', this).html(), $channel);
						});
					});
				},
				create:function(){

					//make channel-list draggable-n-droppable
					makeSortableChannels();

					$('#btnSaveChannelConfig').click(function(){
						$('body').css('cursor', 'wait');
						//$('#loadingIcon').show();

						var $channelWidgetInstance = $('#channel-config-dialog').data('channel-widget');
						var widgetData = {id: $channelWidgetInstance.attr('widget-id'), instanceid: $channelWidgetInstance.attr('widget-instance-id')};

						var channelData = {
								widgetid: widgetData.id,
								widgetinstanceid: widgetData.instanceid,
								pagetemplateid: $('#txtPageTemplateId').val(),
								channels: []
						};

						//populate 'channels' property
						$('#channel-config-dialog .channel-list .main-channel-container').each(function(index){
							var $channel = $('> .channel-item', this);
							var mainChannelId = $channel.attr('data-channel-id');

							var channelObj = {
								id: mainChannelId,
								title: $('.channel-title div', $channel).text(),
								displayorder:index,
								subchannels : []
							}
							//populate 'subchannels' property
							$('.sub-channel-container .channel-item', this).each(function(index){
								//add sub channel data
								channelObj.subchannels.push({
									id: $(this).attr('data-channel-id'),
									title: $('.channel-title div', this).text(),
									displayorder:index,
									parentchannelid: mainChannelId,
									subchannels : []
								});
							});

							//add main channel data
							channelData.channels.push(channelObj);
						});

						//submit the channel data
						$.ajax({
							url:$('#hiddenData').attr('base-url') + '/index.php/ajax/api/widget/saveChannelWidgetConfig',
							data: {data: JSON.stringify(channelData)}, //@todo: older browsers don't have JSON object, jQuery doesn't have equivalent method; use https://github.com/douglascrockford/JSON-js
				  			type:'POST',
				  			dataType: 'json',
				  			complete:function(){
								$('body').css('cursor', 'auto');
								//$('#loadingIcon').hide();
							},
				  			success:function(result){
								//check results
//alertObjectProperties(result);
								if (result && result.widgetinstanceid > 0 && result.channels && result.channels.length > 0){
									//update the channel widget instance on the main page
									var $widgetChannelList = $('.widget-channel-list', $channelWidgetInstance).empty();
									$.each(result.channels, function(i, mainChannel){
										var $parentChannel = $('<li data-channel-id="{0}">Main Channel: <span>{1}</span><ul class="widget-subchannel-list"></ul></li>'.format(mainChannel.id, mainChannel.title)).appendTo($widgetChannelList);
										$.each(mainChannel.subchannels, function(j, subChannel){
											$('<li data-channel-id="{0}">Sub-Channel: <span>{1}</span></li>'.format(subChannel.id, subChannel.title)).appendTo($('.widget-subchannel-list', $parentChannel));
										});
									});

									$channelWidgetInstance.attr('widget-instance-id', result.widgetinstanceid);
									$('.canvas-widget-content', $channelWidgetInstance).removeClass('hide');

									//empty the channel list
									$('#channel-config-dialog .channel-list').empty();

									//close channel config overlay
									$('#channel-config-dialog').dialog('close');
								}
								else {
									initErrorDialog();
									showErrorDialog('<span>Error saving the channels.<br /><br />Please try again.</span>');
								}
							},
							error:function(xhr){
								initErrorDialog();
								showErrorDialog('<span>Error saving the channels.<br />(Error code {0})<br /><br />Please try again.</span>'.format(xhr.status));
							}
						});
					});

					$('#btnCancelChannelConfig').click(function(){
						$('#confirm-dialog').data('confirm-mode', 'cancel');
						$('#confirm-dialog').dialog('option', 'title', 'Cancel Edit?');
						$('#confirm-dialog .dialog-content').html('<p>Do you really want to cancel editing the Channel Module?</p><p>Warning! All changes will be discarded.</p>');
						$('#confirm-dialog').dialog('open');
					});
				}
			});

			//Confirm dialog
			$('#confirm-dialog').dialog({
				autoOpen:false,
				modal:true,
				resizable:false,
				closeOnEscape:false,
				width:500,
				dialogClass:'sb-dialog-container confirm-dialog-container shadow-dark',
				create:function(){
					$('#btnYes').click(function(){
						var mode = $('#confirm-dialog').data('confirm-mode');
						var $draggableItem = $('#confirm-dialog').data('widget-draggable-item');
						switch (mode){
							case 'deletewidget':
								$draggableItem.remove();
								break;

							case 'deletechannel':
								var $subChannelContainer = $('.sub-channel-container', $draggableItem.parent());

								//delete channel/subchannel
								$draggableItem.remove();

								if ($subChannelContainer.is(':empty')){
									$subChannelContainer.parent().slideUp('fast', function(){
										var $rightCol = $('.canvas-layout.show > div.has-adjacent-left-col');
										if ($rightCol.length > 0) {
											var $leftCol = $('.canvas-layout.show > div.has-adjacent-right-col');
											if ($rightCol.height() > $leftCol.height()) {
												$leftCol.height($rightCol.height());
											}
											else $leftCol.height('auto');

										}
										$(this).remove();
										adjustDivider();
									});
								}
								else { //contains sub channel(s), so make the first sub channel as the main channel
									$('.channel-item:first', $subChannelContainer).insertBefore($subChannelContainer);

								}
								break;

							default: //Cancel Edit Channel
								//delete added channels
								$('#channel-config-dialog .channel-list').empty();
								$('#channel-config-dialog').dialog('close');
						}

						$('#confirm-dialog').dialog('close');
					});

					$('#btnNo').click(function(){
						$('#confirm-dialog').dialog('close');
					});
				},
				open:function(){
					$('#btnNo').focus();
				}
			});

			selectLayout($('.canvas-layout.show').attr('id'));
		}

		function selectLayout(targetLayout){
			if (!currentLayout) { //initialize current layout

				//only enable target layout's displaysections[] fields
				$('.canvas-layout.hide input[type=hidden]').attr('disabled', 'disabled');
				$('#' + targetLayout + ' input[type=hidden]').removeAttr('disabled');

				currentLayout = targetLayout;
				return;
			}
			else if (currentLayout == targetLayout) { //do nothing if the same layout is already selected
				return;
			}
			else { //put widgets to the target layout in the same sections as the current layout

				//only enable target layout's displaysections[] fields
				$('.canvas-layout.hide input[type=hidden]').attr('disabled', 'disabled');
				$('#' + targetLayout + ' input[type=hidden]').removeAttr('disabled');

				if (sectionCount[currentLayout] > sectionCount[targetLayout]) { //current layout has more sections than the target layout
					//put the widgets to the available target layout sections
					for (var i=0; i<sectionCount[targetLayout]; i++) {
						$('#' + currentLayout + ' > div.section-' + i +' > div.canvas-widget').appendTo('#' + targetLayout + ' > div.section-' + i);
					}
					//put the widgets from the excess section(s) of current layout to the unassigned widgets container
					var showUnassignedWidgets = false;
					for (i=sectionCount[targetLayout]; i<sectionCount[currentLayout]; i++) {
						if ($('#' + currentLayout + ' > div.section-' + i +' > div.canvas-widget').length > 0) {
							$('#' + currentLayout + ' > div.section-' + i +' > div.canvas-widget').insertBefore($('.unassigned-widget-list div.clear:last'));
							showUnassignedWidgets = true;
						}
					}
					if (showUnassignedWidgets) {
						$('.unassigned-widget-list').show();
					}
				}
				else { //number of sections in the current layout is <= to that of the target layout
					$('.unassigned-widget-list').hide().find('div.canvas-widget').remove();
					for (var i=0; i<sectionCount[currentLayout]; i++) {
						$('#' + currentLayout + ' > div.section-' + i +' > div.canvas-widget').appendTo('#' + targetLayout + ' > div.section-' + i);
					}
				}
				adjustDivider();
			}
			currentLayout = targetLayout;
		};

		//this function should be accessible outside
		window.addWidgets = function(widgets, manualAdd) {
			//validate widgets array
			if (!$.isArray(widgets) || widgets.length == 0) {
				return;
			}
			$('#loadingIcon').show();
			$('body').css('cursor', 'wait');

			//get widget templates via AJAX
			$.ajax({
				url:$('#hiddenData').attr('base-url') + '/index.php/ajax/admin-template/widget',
				data:({
					'widgets': widgets,
	  				'pagetemplateid': $('#txtPageTemplateId').val()
	  			}),
	  			type:'POST',
	  			dataType: 'json',
	  			complete:function(){
					$('body').css('cursor', 'auto');
					$('#loadingIcon').hide();
				},
	  			success:function(result){
//alertObjectProperties(result);

					if (result && $.isArray(result.widgets)){
						$.each(result.widgets, function(index, widget){
							if (!widget.widgetid || Number(widget.widgetid) < 1 || !widget.template) return true; //skip
							var section = (widget.displaysection && Number(widget.displaysection) > 0) ? widget.displaysection : 0;

							//append widget template to the DOM
							$(widget.template)
						  	.appendTo($('.canvas-layout.show .canvas-widget-list.section-' + section).height('auto'))
						  	.find('.canvas-widget-title a').click(function(){
						  		$('body').css('cursor', 'wait');
						  		var $widgetContainer = $(this).closest('.canvas-widget');
						  		var widgetId = $widgetContainer.attr('widget-id');
						  		var widgetName = $(this).text();

						  		$('#config-dialog .widget-loader').show();
						  		$('#config-dialog .widget-name h1').text(widgetName);
						  		$('#config-dialog .dialog-content .widget-config-container').hide().empty().removeClass('error');
						  		$('#config-dialog').dialog('open');

						  		//get config items of the selected widget
						  		$.ajax({
						  			url:$('#hiddenData').attr('base-url') + '/index.php/ajax/api/widget/fetchConfigSchema',
						  			data:({
						  				widgetid: widgetId,
						  				widgetinstanceid: $widgetContainer.attr('widget-instance-id')||'', //if this widget instance has been configured before, its widget instance id exists, so use it
						  				pagetemplateid: $('#config_pagetemplateid').val()||$('#txtPageTemplateId').val(),
						  				configtype: 'admin'
						  			}),
						  			type:'POST',
						  			dataType: 'json',
						  			complete:function(){
						  				$('body').css('cursor', 'auto');
						  			},
						  			success:function(result){
						  				if (result) {
						  					//set hidden fields
						  					$('#config_widgetid').val(result.widgetid);
						  					$('#config_widgetinstanceid').val(result.widgetinstanceid);
						  					$('#config_pagetemplateid, #txtPageTemplateId').val(result.pagetemplateid);

						  					//remember id of this widget instance for subsequent requests
						  					$widgetContainer.attr('widget-instance-id', result.widgetinstanceid);
											if (!result.configs || result.configs.length == 0) {
												$('.widget-config-container').html('No configurations found.').addClass('error');
												$('#btnSaveConfig').attr('disabled', 'disabled');
												$('#btnCloseConfig').focus();
											}
											else {
							  					//loop through all the config items
							  					var idx = 0; //result.configs is an object literal and not an indexed array so we cannot use $.each index for math operations.
							  					$.each(result.configs, function(index, config){
							  						var $configValue;
							  						//convert config item to corresponding UI control
							  						switch(config.type){
							  							case 'Text':
							  								$configValue = $('<input type="text" />')
							  												.attr({
							  													name: 'data[' + config.name + ']'
							  												})
							  												.css('width', '100%')
							  												.val(config['default']);
							  								break;
							  							case 'LongText':
							  								$configValue = $('<textarea />')
							  												.attr({
							  													rows:3,
							  													name: 'data[' + config.name + ']'
							  												})
							  												.css('width', '100%')
							  												.text(config['default']);
							  								break;
							  							case 'YesNo':
							  								var $options = {
							  									'option_1' : $('<input type="radio" value="1" />')
							  												.attr({
						  														name: 'data[' + config.name + ']',
						  														id: config.name + '_1'
						  													}),
						  										'label_1': $('<label />')
							  													.attr({'for': config.name + '_1'})
							  													.text('Yes'),
							  									'option_0' : $('<input type="radio" value="0" />')
							  												.attr({
						  														name: 'data[' + config.name + ']',
						  														id: config.name + '_0'
						  													}),
						  										'label_0': $('<label />')
							  													.attr({'for': config.name + '_0'})
							  													.text('No')
							  								}

							  								$options['option_'+config['default']].attr('checked', 'checked');
							  								$configValue = $('<div />')
							  									.append(
							  										$options['option_1'], $options['label_1'],
							  										$options['option_0'], $options['label_0']
							  									);
							  								break;
							  						}

							  						//put * if field is required
							  						$requiredMark = $('<div />')
							  										.addClass('config-required-mark left')
							  										.append(function(){
							  											return (config.isRequired==1) ? '*':'&nbsp;'
							  										});

							  						//disable field if config is not editable
							  						if (config.isEditable==0) {
							  							if (config.type=='YesNo') {
							  								$configValue.find('input').attr('disabled', 'disabled');
							  							}
							  							else {
							  								$configValue.attr('disabled', 'disabled');
							  							}
							  						}

													//append the config row
							  						$('#config-dialog .dialog-content .widget-config-container').append(
							  							$('<div></div>')
							  								.addClass(function(){
							  									return "config-row" + (((++idx) % 2 != 0) ? ' odd':'');
							  								})
							  								.append(
								  								$('<div></div>').addClass('config-label left').html(config.label),
								  								$requiredMark,
								  								$('<div></div>').addClass('config-value left').append($configValue),
								  								$('<div></div>').addClass('clear')
							  							)
							  						);
												});
							  				}
							  			}
						  				$('#config-dialog .dialog-content .widget-config-container').show();
										$('#config-dialog .widget-loader').hide();
						  			},
						  			error:function(xhr, statusText, error){
						  				initErrorDialog(null, function(){
						  					$('#config-dialog').dialog('close');
										});
										showErrorDialog('<span>Error retrieving the configuration for \'{0}\' widget.<br /><br />Please try again.</span>'.format(widgetName));
										$('#config-dialog .widget-loader').hide();
						  			}
								});
						  		return false;
						  	});

							//un-select selected widget that was just added via Add Widget button
							if (manualAdd) $('#widget_' + widget.widgetid + ' .widget-border').trigger('click');
						});

						adjustDivider();
					}
					else { //widgets in the ajax response is not an array - unlikely to occur but let's catch it for safety
						initErrorDialog();
						showErrorDialog('<span>Invalid server response.<br /><br />Please try again.</span>');
					}
				},
				error:function(xhr){
					initErrorDialog();
					showErrorDialog('<span>Error adding the widget(s).<br />(Error code {0})<br /><br />Please try again.</span>'.format(xhr.status));
				}
			});

			return false;
		}

		function adjustDivider(){
			var $rightCol = $('.canvas-layout.show > div.has-adjacent-left-col');
			var $leftCol = $('.canvas-layout.show > div.has-adjacent-right-col');
			if ($rightCol.length > 0 && $leftCol.length > 0) {

				if ($rightCol.height() > $leftCol.height()) {
					$leftCol.height($rightCol.height());
				}
				else if ($rightCol.height() < $leftCol.height()) {
					$leftCol.height('auto');
				}
			}
		}

		function makeSortableChannels(){
			$('.channel-list').sortable({
				//connectWith: ".connectedSortableChannel",
				placeholder: "main-channel-container-highlight clear",
				update: function(event, ui){
					ui.item.css('z-index', '0'); //for IE7
				},
				sort:function(event, ui){
					ui.item.addClass('shadow');
					//adjustDivider();
				},
				start:function(event, ui){
					ui.item.removeClass('shadow');
					if ($.browser.msie && parseInt($.browser.version, 10) == 8){ //IE8 widget height is bigger
						ui.item.height(ui.item.height()-4);
					}
					ui.item.css('z-index', '99999'); //for IE7
					ui.placeholder.height(ui.item.height());
				},
				over:function(event, ui){
					console.debug('list over');
				},
				receive:function(event, ui){
					console.debug('list receive');
				},
				out:function(event, ui){
					console.debug('list out');
				},
				handle:'.grip-icon-main',
				items:'.main-channel-container'
			});
		}

		function makeSortableMainChannels(){
			$('.channel-list .main-channel-container').sortable({
				connectWith: ".sub-channel-container",
				//placeholder: "channel-item-highlight round-corner5",
				update: function(event, ui){console.debug('main update');
					ui.item.css('z-index', '0'); //for IE7

					var $mainChannelContainer = ui.item.closest('.main-channel-container');

					//check the main channel container from where the item was dropped to
					//check if there is a main channel or not; if none, then make the first sub channel as the main channel
					//var $mainChannelContainer = ui.item.closest('.main-channel-container');
					if ($('> .channel-item:not(.channel-temp-filler)', $mainChannelContainer).length == 0){
						$('.channel-item:first', ui.item.parent()).insertBefore(ui.item.parent());
					}

					//there cannot have 2 main channels in the same main channel container
					if ($('> .channel-item:not(.channel-temp-filler)', $mainChannelContainer).length > 1) {
						var $subChannelContainer = $('.sub-channel-container', $mainChannelContainer);
						if ($subChannelContainer.is(':empty')){
							$('> .channel-item:not(.channel-temp-filler):last', $mainChannelContainer).appendTo($subChannelContainer);
						}
						else {
							$('> .channel-item:not(.channel-temp-filler):last', $mainChannelContainer).prependTo($subChannelContainer);
						}
					}
				},
				sort:function(event, ui){
					//ui.item.addClass('shadow');
					//adjustDivider();
				},
				start:function(event, ui){
					/*ui.item.removeClass('shadow');
					if ($.browser.msie && parseInt($.browser.version, 10) == 8){ //IE8 widget height is bigger
						ui.item.height(ui.item.height()-4);
					}*/
					ui.item.css('z-index', '99999'); //for IE7
					//ui.placeholder.height(ui.item.height());
					//$('.sub-channel-container', $mainChannel).sortable('option', 'items', );
				},
				over:function(event, ui){
					console.debug('main over');
				},
				receive:function(event, ui){
					console.debug('main receive');
				},
				out:function(event, ui){
					console.debug('main out');
				},
				handle:'.grip-icon-item',
				items:'.channel-item'
			});
		}

		function makeSortableSubChannels($mainChannel){
			$('.sub-channel-container', $mainChannel).sortable({
				connectWith: ".main-channel-container",
				//placeholder: "channel-item-highlight round-corner5",
				//forcePlaceholderSize:true,
				update: function(event, ui){console.debug('sub update');
					ui.item.css('z-index', '0'); //for IE7
					//console.debug(ui.sender.attr('class'))
					//check the main channel container from where the item was dragged from
					if (ui.sender && ui.sender.hasClass('main-channel-container')){
						//remove the main channel container where the channel item came from if it has no sub channel items
						var $subChannelContainer = $('.sub-channel-container', ui.sender);
						if ($subChannelContainer.is(':empty')){
							ui.sender.slideUp('fast', function(){$(this).remove()});
							//ui.sender.remove();
						}
						else { //but if it has sub channels, make the first sub channel as the main channel
							$('.channel-item:first', $subChannelContainer).insertBefore($subChannelContainer);

						}
					}
					//check the main channel container from where the item was dropped to
					//check if there is a main channel or not; if none, then make the first sub channel as the main channel
					//var $mainChannelContainer = ui.item.closest('.main-channel-container');
					//if ($('> .channel-item', ui.item.closest('.main-channel-container')).length == 0){
					//	$('.channel-item:first', ui.item.parent()).insertBefore(ui.item.parent());
					//}
				},
				sort:function(event, ui){
					//ui.item.addClass('shadow');
					//adjustDivider();
				},
				start:function(event, ui){
					/*ui.item.removeClass('shadow');
					if ($.browser.msie && parseInt($.browser.version, 10) == 8){ //IE8 widget height is bigger
						ui.item.height(ui.item.height()-4);
					}*/
					ui.item.css('z-index', '99999'); //for IE7
					//ui.placeholder.height(ui.item.height());

				},
				over:function(event, ui){
					console.debug('sub over');
					if (ui.sender){
						ui.item.clone().css({'position':'static', 'visibility': 'hidden'}).addClass('channel-temp-filler').insertBefore($('.sub-channel-container', ui.sender));
					}
				},
				receive:function(event, ui){
					console.debug('sub receive');
				},
				out:function(event, ui){
					console.debug('sub out');
					if (ui.sender){
						$('.channel-temp-filler', ui.sender).remove();
					}
				},
				handle:'.grip-icon-item',
				items:'.channel-item'
			});
		}

		function addChannel(channelId, channelTitle){
			var $addedChannel =
				$('<div class="main-channel-container shadow">\
					<div class="grip-icon grip-icon-main left"><div>&uml;</div><div>&uml;</div><div>&uml;</div><div>&uml;</div><div>&uml;</div></div>\
					<div class="channel-item round-corner5 shadow" data-channel-id="{0}">\
						<div class="channel-item-inner">\
							<div class="grip-icon grip-icon-item left"><div>&uml;</div><div>&uml;</div><div>&uml;</div><div>&uml;</div><div>&uml;</div></div>\
							<div class="channel-title"><div title="Click text to edit title">{1}</div><input type="text" name="channeltitle" value="{1}" /></div>\
							<div class="close-button">x</div>\
							<div class="clear"></div>\
						</div>\
					</div>\
					<div class="sub-channel-container"></div>\
			  </div>'.format(channelId, channelTitle))
				.appendTo($('.channel-list'));

			//enable drag n drop to the added channel
			makeSortableMainChannels();
			makeSortableSubChannels($addedChannel);

			return $addedChannel;
		}

		function addSubChannel(channelId, channelTitle, $parentChannel){
			$('<div class="channel-item round-corner5 shadow" data-channel-id="{0}">\
					<div class="channel-item-inner">\
						<div class="grip-icon grip-icon-item left"><div>&uml;</div><div>&uml;</div><div>&uml;</div><div>&uml;</div><div>&uml;</div></div>\
						<div class="channel-title"><div title="Click text to edit title">{1}</div><input type="text" name="channeltitle" value="{1}" /></div>\
						<div class="close-button">x</div>\
						<div class="clear"></div>\
					</div>\
			   </div>'.format(channelId, channelTitle))
			.appendTo($('.sub-channel-container', $parentChannel));
		}

		initPage();
	});
})(jQuery);