
String.prototype.hashCode = function(){
/* to test string equalities
 * 
 * http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
 */
    var hash = 0;
    if (this.length == 0) return hash;
    for (i = 0; i < this.length; i++) {
        char = this.charCodeAt(i);
        hash = ((hash<<5)-hash)+char;
        hash = hash & hash; // Convert to 32bit integer
    }
    return hash;
}

var chgDialog;

$(function(){
	setContactButtonBarState();
	for(var i = 0, max = CHTR.contacts.length; i < max; i+=1){

		var contact  = CHTR.contacts[i],
			chkBxId  = 'checkbox-for-contact-'+contact.id,
			$tmpl    = getTemplate("contact-display");

		// set the data-contact-id property
		$tmpl
			.find('tr')
			.prop('data-contact-id',contact.id);

		// set the label for the checkbox element
		$tmpl
			.find('label')
			.prop('for',chkBxId)
			.text( "Checkbox for " + contact.getFullName() );

		// set the checkbox element properties
		$tmpl
			.find('input')
			.prop('id',chkBxId);

		// set the name cell
		$tmpl
			.find('.contact-list-name')
			.text( contact.getFullName() );

		// set the primary email cell
		$tmpl
			.find('.contact-list-email')
			.text( contact.getPrimaryEmailAddress() );

		// set the primary phone cell
		$tmpl
			.find('.contact-list-phone')
			.text( contact.getPrimaryPhoneNumber() );

		// set the primary email cell
		$tmpl
			.find('.contact-list-address')
			.text( contact.getPrimaryAddress() );

		$tmpl.data('contact-id',contact.id);

		$('#contacts-list').append($tmpl);

	}

	chgDialog = $('#prompt-for-save-contact-changes').dialog({
		resizeable: false,
		dialogClass: "no-close",
		height: 181,
		modal: true,
		buttons: {
			"Yes" : function(){ 
				toggleScreenOverlay();
				$(this).dialog("close");
				return false;
			},
			"No"  : function(){ 
				var tbody = $('#contacts-list tbody.contact-edit-form');
				toggleScreenOverlay();
				$(this).dialog("close");
				tbody.data('hash-code', getHashCode(tbody.find('form')[0]) );
				closeEditForm();
				return true;
			}
		}
	});

	chgDialog.dialog("close");

	$("#add-contact-button").click( showContactEditForm );

	$("#edit-contact-pane-close-button").click( closeEditForm );

	$(".contact-display").click( showContactExtendedView );

	$('#contact-list-checkbox-select-all').click(function(e){
		var chkd = $(this).prop('checked');
		$('#contacts-list td:first-child input[type="checkbox"]').prop('checked', chkd);
		if(chkd){
			$('.contact-display').addClass('active')
		} else {
			$('.contact-display').removeClass('active');
		}
	});

	$(".contact-display td:first-child input[type='checkbox']").click(function(e){
		e.stopPropagation();
		var totalList  = $('#contacts-list td.contact-list-checkbox').length;
		var numChecked = $('#contacts-list td.contact-list-checkbox :checked').length;

		if(numChecked === 0){
			setContactButtonBarState();
		} else if (numChecked === 1) {
			setContactButtonBarState('single-checkbox');
		} else if( numChecked > 1){
			setContactButtonBarState('multi-checkbox');
		}

		var chkHeader = (totalList===numChecked)? true : false;
		$('#contact-list-checkbox-select-all').prop('checked',chkHeader);

		if($(this).prop('checked')){
			$(this).parents('tr').addClass('active');
		} else {
			$(this).parents('tr').removeClass('active');
		}
	});

	$('.contact-group-button').click(function(e){
		$('.contact-group-button').removeClass('active');
		$(this).addClass('active');
	});

	// begin settings onload events
	
});

function closeEditForm(e)
{
	var chgd = editFormHasChanged(),
		form = $('#contacts-list tbody.contact-edit-form'),
		id   = form.data('contact-id');

	if(chgd){
		toggleScreenOverlay();
		return chgDialog.dialog("open");
	} else {
		form.remove();
		$('#contacts-list tbody').each(function(i,tbody){
			if( id === $(tbody).data('contact-id') ){
				$(tbody).show();
			}
		});
		setContactButtonBarState();
		return true;
	}
}

function editFormHasChanged()
{
	var	form  = $('#contacts-list .contact-edit-form'),
		hcode = getHashCode( form.find('form')[0] );

	if( !form.is(":visible") ){
		return false;
	}

	return form.data('hash-code') !== hcode;
}

function toggleScreenOverlay()
{
	var overlay = $(".ui-dialog-overlay");
	if(overlay.is(":visible")){
		overlay.hide();
	} else {
		overlay.show();
	}
}

function getTemplate(name)
{
	var tmplName = name+'-template';
	return $('.'+tmplName).clone().removeClass(tmplName);
}

function showContactExtendedView()
{
	var currentId  = $(this).prop('data-contact-id'),
		chkBxId    = 'x-contact-id-'+currentId+'-checkbox',
		contact;

	// reveal the previously hidden contacts, if any, then hide self
	$('#contacts-list tbody').show();
	$(this).parent('tbody').hide();

	// remove a previous extended display if it exists
	$('#contacts-list .contact-display-extended').parent('tbody').remove();

	// retrived template
	$tmpl = getTemplate('contact-display-extended');

	// TODO: change the CHTR.contacts array to a hash
	//       accessing the contact directly by its id
	//       e.g.:
	//         CHTR.contacts = [
	//           {id_12345:new Contact(...)},
	//           {id_12346:new Contact(...)}.
	//            ...
	//         ];
	//       Thus: contact = CHTR.contacts.id_12345;

	for(var i = 0, max = CHTR.contacts.length; i < max; i += 1){
		var c = CHTR.contacts[i];
		if(c.id == currentId){
			contact = c;
			break;
		}
	}

	$tmpl.data('contact-id',contact.id);
	
	// set button event handlers
	$tmpl
		.find('.x-contact-edit-button')
		.data('contact-id',contact.id)
		.click( showContactEditForm )
	// set template values
	$tmpl
		.find('label')
		.prop('for',chkBxId)
		.text( 'Checkbox for '+ contact.getFullName() );

	$tmpl
		.find('input')
		.prop('id',chkBxId)
		.prop('checked',true)
		.click(function(e){
			$('#contacts-list .contact-display-extended').parent('tbody').prev().show();
			$('#contacts-list .contact-display-extended').parent('tbody').remove();
		});

	$tmpl
		.find('.x-contact-fname')
		.text( contact.firstName );

	$tmpl
		.find('.x-contact-lname')
		.text( contact.lastName );

	// Add email addresses
	for(var i = 0, max = contact.email.length; i < max; i += 1){
		var email = contact.email[i],
			loc   = email.location + " Email:",
			key   = $('<div class="x-contact-key"></div>').text(loc),
			val   = $('<div class="x-contact-val"></div>').text(email.email);

		$tmpl
			.find('.x-contact-email')
			.append(key)
			.append(val);
	}

	// Add phone numbers
	for(var i = 0, max = contact.phone.length; i < max; i += 1){
		var ph  = contact.phone[i],
			loc = ph.location + " Phone:",
			key = $('<div class="x-contact-key"></div>').text(loc),
			val = $('<div class="x-contact-val"></div>').text(ph.phone);

		$tmpl
			.find('.x-contact-phone')
			.append(key)
			.append(val);
	}

	// Add physical addresses
	for(var i = 0, max = contact.address.length; i < max; i += 1){
		var addr = contact.address[i],
			loc  = addr.location + " Address:",
			key  = $('<div class="x-contact-key"></div>').text(loc),
			val  = $('<div class="x-contact-val"></div>').text(addr.address);

		$tmpl
			.find('.x-contact-address')
			.append(key)
			.append(val);
	}

	$(this).parent('tbody').after($tmpl);
}

function showContactEditForm(e)
{
	var tmplName  = 'contact-edit-form',
		$tmpl     = getTemplate(tmplName),
		$listTbl  = $('#contacts-list'),
		currentId = $(this).data('contact-id'),
		hashCode  = 0,
		contact, $emailCtrl, $phCtrl, $addrCtrl, answer;

	setContactButtonBarState('edit-view');
	$tmpl.addClass(tmplName);

	// If the id is not defined then this is a requrest for a new
	// contact via the add contact button. Also test to make sure
	// that there is not already a new contact edit form visible
	if(typeof currentId ==='undefined' ){
		if( $('.'+tmplName).is(':visible') ){
			if( closeEditForm(e) ){
				$tmpl.prop('data-hash-code',hashCode);
				$('#contacts-list thead').after($tmpl);
				$("#edit-contact-pane-close-button").click( closeEditForm );
				return;
			}
		} else {
			$tmpl.prop('data-hash-code',hashCode);
			$('#contacts-list thead').after($tmpl);
			$("#edit-contact-pane-close-button").click( closeEditForm );
			return;
		}
	}

	// Otherwise get te contact data and fill the fields before
	// adding to the DOM
	// TODO: change the CHTR.contacts array to a hash
	//       accessing the contact directly by its id
	//       e.g.:
	//         CHTR.contacts = [
	//           {id_12345:new Contact(...)},
	//           {id_12346:new Contact(...)}.
	//            ...
	//         ];
	//       Thus: contact = CHTR.contacts.id_12345;

	for(var i = 0, max = CHTR.contacts.length; i < max; i += 1){
		var c = CHTR.contacts[i];
		if(c.id == currentId){
			contact = c;
			break;
		}
	}

	$tmpl.data('contact-id',contact.id);

	$tmpl
		.find('[name="first-name"]')
		.val( contact.firstName );

	$tmpl
		.find('[name="last-name"]')
		.val( contact.lastName );

	$emailCtrl = $tmpl.find('.email-control-label').remove();

	for(var i = 0, max = contact.email.length; i < max; i += 1){
		var $ctrl = $emailCtrl.clone(),
			email = contact.email[i],
			state = 'toggle-state-',
			id    = email.location.toLowerCase()+'_email',
			lctn  = email.location+' Email';

			state += email.primary? 'on' : 'off';

			$ctrl.find('.keyval-select-button').addClass(state);

			$ctrl
				.find('label')
				.prop('for',id)
				.text(lctn);

			$ctrl
				.find('input')
				.prop('placeholder',lctn)
				.prop('name',id)
				.prop('id',id)
				.val(email.email);

			// $('#contacts-list .contact-edit-form-email-addresses').append( $ctrl );
			$tmpl.find('.contact-edit-form-email-container').append( $ctrl );
			
	}

	$phCtrl = $tmpl.find('.phone-control-label').remove();

	for(var i = 0, max = contact.phone.length; i < max; i += 1){
		var $ctrl = $phCtrl.clone(),
			phone = contact.phone[i],
			state = 'toggle-state-',
			id    = phone.location.toLowerCase()+'_phone',
			lctn  = phone.location+' Phone';

			state += phone.primary? 'on' : 'off';

			$ctrl.find('.keyval-select-button').addClass(state);

			$ctrl
				.find('label')
				.prop('for',id)
				.text(lctn);

			$ctrl
				.find('input')
				.prop('placeholder',lctn)
				.prop('name',id)
				.prop('id',id)
				.val(phone.phone);

			// $('#contacts-list .contact-edit-form-email-container').append( $ctrl );
			$tmpl.find('.contact-edit-form-phone-container').append( $ctrl );
			
	}

	$addrCtrl = $tmpl.find('.address-control-label').remove();

	for(var i = 0, max = contact.address.length; i < max; i += 1){
		var $ctrl = $addrCtrl.clone(),
			addr  = contact.address[i],
			state = 'toggle-state-',
			id    = addr.location.toLowerCase()+'_address',
			lctn  = addr.location+' Address';

			state += addr.primary? 'on' : 'off';

			$ctrl.find('.keyval-select-button').addClass(state);

			$ctrl
				.find('label')
				.prop('for',id)
				.text(lctn);

			$ctrl
				.find('textarea')
				.prop('placeholder',lctn)
				.prop('name',id)
				.prop('id',id)
				.val(addr.address);

			// $('#contacts-list .contact-edit-form-email-container').append( $ctrl );
			$tmpl.find('.contact-edit-form-address-container').append( $ctrl );
			
	}

	$tmpl.data('hash-code', getHashCode( $tmpl.find('form')[0] ) )
	$tmpl.find('#edit-contact-pane-close-button').click( closeEditForm );
	$(this).closest('tbody').replaceWith( $tmpl );

}

function getHashCode(form)
{
	var state;
	$.each( $(form).serializeArray(),function(i,input){
		state += input.value;
	});
	return state.hashCode();
}

function setContactButtonBarState(state)
{
	var buttons;
	switch(state)
	{
		case 'single-checkbox':
			buttons = {
				'new-group-button':true,
				'sort-contacts-dropdown-button':false,
				'select-contacts-dropdown-button':true,
				'more-contacts-dropdown-button':true,
				'edit-contact-button':true,
				'email-contact-button':true,
				'delete-contact-button':true,
				'save-contact-button':false,
				'close-edit-contact-button':false,
				'share-contact-button':true
			}
			break;
		case 'multi-checkbox':
			buttons = {
				'new-group-button':true,
				'sort-contacts-dropdown-button':false,
				'select-contacts-dropdown-button':true,
				'more-contacts-dropdown-button':true,
				'edit-contact-button':false,
				'email-contact-button':false,
				'delete-contact-button':true,
				'save-contact-button':false,
				'close-edit-contact-button':false,
				'share-contact-button':true
			}
			break;
		case 'edit-view':
			buttons = {
				'new-group-button':false,
				'sort-contacts-dropdown-button':false,
				'select-contacts-dropdown-button':false,
				'more-contacts-dropdown-button':false,
				'edit-contact-button':false,
				'email-contact-button':false,
				'delete-contact-button':true,
				'save-contact-button':true,
				'close-edit-contact-button':true,
				'share-contact-button':false
			}
			break;

		default:
			buttons = {
				'new-group-button':true,
				'sort-contacts-dropdown-button':true,
				'select-contacts-dropdown-button':true,
				'more-contacts-dropdown-button':false,
				'edit-contact-button':false,
				'email-contact-button':false,
				'delete-contact-button':false,
				'save-contact-button':false,
				'close-edit-contact-button':false,
				'share-contact-button':false
			}
	}

	for(var btn in buttons){
		var key = "#" + btn;
		(buttons[btn])? $(key).show() : $(key).hide();
	}
}