/*
 * 
 * Find more about this app by visiting
 * http://miniapps.co.uk/
 *
 * Copyright (c) 2010 Alex Gibson, http://miniapps.co.uk/
 * Released under MIT license
 * http://miniapps.co.uk/license/
 *
 * Version 1.5 - Last updated: March 24 2010
 * 
 */

var checklistApp = {

/*Retrieves all list items from localStorage and sorts in an alphabetically ordered list.*/
getAllItems: function() {

   	var checklist, myArray, i, j, completed, total, listlength;
   	
   	checklist = ""; /*a variable for storing html, once we process all items from localStorage.*/
  	myArray = []; /*our array of items for processing.*/
   	i = 0; /*iterator variable i.*/
   	j = 0; /*iterator variable j.*/
   	completed = 0; /*the total number of checked items in our list.*/
   	total = 0; /*the total number of items in our checklist.*/
   	listlength = localStorage.length-1; /*the total number of items held in localStorage.*/
   		
   	/*get all items from localStorage and push them one by one into an array.*/
   	for (i = 0; i <= listlength; i++) {
   	
    	var item = localStorage.key(i);
    	myArray.push(item);
    }
    
    /*sort the array into alphabetical order.*/
    myArray.sort();
    
    /*process every item in the sorted array.*/
    for (j = 0; j <= listlength; j++) {
    
    	var sorteditem = myArray[j];
    	
    	/*if the item is not a temporary item (i.e. stored on key up for input).*/
    	if (sorteditem !== 'inputvalue') {
    	
    		/*is the item checked already?.*/
     		if (localStorage.getItem(sorteditem) === '1') {
     		
     			checklist += '<li><input type="checkbox" checked/><label class="done">' + sorteditem + '</label><span class="delete">&times;</span></li>';
     			
     			/*add 1 to the total number of items and checked items.*/
     			completed ++;
     			total ++;
     		}
     		/*is the item unchecked?.*/
     		else if (localStorage.getItem(sorteditem) === '0') {
     		
     			checklist += '<li><input type="checkbox" /><label>' + sorteditem + '</label><span class="delete">&times;</span></li>';
     			
     			/*add 1 to the total number of items.*/
     			total ++;
     		}
     	}
     	else {
     		/*the item is temporarily stored for key up. place back in the form input box instead.*/
     		document.querySelector('#name').value = localStorage.getItem(sorteditem);
     	}
   	}
   	
   	/*were there no items in the checklist?.*/
   	if (checklist === "") {
   		checklist = '<li class="empty">List empty</li>';
   	}
   	
   	/*calculate and update the readout for total and completed items.*/
   	document.querySelector('#remaining').innerHTML = total - completed;
   	document.querySelector('#total').innerHTML = total;
   	
   	/*if all  items are completed and the mail list button is showing, hide it.*/
   	if (completed === total) {
   		document.querySelector('#maillist').style.display = 'none';
   	}
   	
   	/*update all items on the screen.*/
   	document.querySelector('#checklist').innerHTML = checklist;
   	
   	/*remove bottom border on last child of the dynamic list.*/
   	document.querySelector('#checklist').lastChild.style.border = '0';
},

/*Event delegation to capture click events on checkboxes and list items, and delete 'x' buttons.*/
eventDelegation: function() {

	/*get the list of items.*/
	var listitems = document.querySelector('#checklist');
	
	/*capture onclick events.*/
	listitems.onclick = function (e) {
	
		var event = e,
			target = event.target;
			
		/*if the click was on a <label> element.*/	
		if(target.tagName.toLowerCase() === 'label') {
		
			var name = target.innerHTML,
			data;
			
			/*toggle the check flag.*/
			if (target.previousSibling.checked) {
				data = 0;
			}
			else {
				data = 1;
			}
			/*save item in localStorage.*/
			try {
				localStorage.setItem(name, data);
			} catch (e) {
			
				if (e == QUOTA_EXCEEDED_ERR) {
					alert('Quota exceeded!');
				}
			}
			/*update view.*/
			checklistApp.getAllItems();
		}
		/*if the click was on an <input> element, i.e. the checkbox.*/
		else if(target.tagName.toLowerCase() === 'input') { 
		
			var name = target.nextSibling.innerHTML,
				data;
				
			/*toggle the check flag.*/	
			if (target.checked) {
				data = 1;
			}
			else {
				data = 0;
			}
			/*save item in localStorage.*/
			try {
				localStorage.setItem(name, data);
			} catch (e) {
			
				if (e == QUOTA_EXCEEDED_ERR) {
					alert('Quota exceeded!');
				}
			}
			/*update view.*/
			checklistApp.getAllItems();
		}
		/*if the click was on an <span> element, i.e. the delete item icon.*/
		else if(target.tagName.toLowerCase() === 'span') {
			
			/*ask for confirmation of delete.*/
			var name = target.previousSibling.innerHTML,
				answer = confirm("Delete item: " + name + "?");
			/*if yes.*/
			if (answer) {
				/*delete item from localStorage.*/
				localStorage.removeItem(name);
				/*update view.*/
				checklistApp.getAllItems();
			}
		}
	}
},

/*adds a new item to localStorage.*/
addNewItem: function() {

	var name, data;
	
	name = document.querySelector('#name').value;
	data = 0;
		
	/*strip html tags.*/
	strippedString = name.replace(/(<([^>]+)>)/ig, "");
		
	/*encode special characters.*/
	strippedString = strippedString.replace(/&/,"&amp;");
	strippedString = strippedString.replace(/</,"&lt;");
	strippedString = strippedString.replace(/>/,"&gt;");
		
	/*add the item.*/
	if (strippedString !== "") {
	
		try {
			localStorage.setItem(strippedString, data);
		} catch (e) {
			if (e == QUOTA_EXCEEDED_ERR) {
				alert('Quota exceeded!');
			}
		}
		/*clear the input field value.*/
   		document.querySelector('#name').value = "";
   		/*remove the item from temporary keyup localStorage.*/
   		localStorage.removeItem('inputvalue');
   		/*update view.*/
   		checklistApp.getAllItems();
   }
   else {
   		alert('Nothing to add!');
   }
   /*clear up.*/
   delete checklistApp.addNewItem;
},

/*deletes all checked items in the list.*/
deleteChecked: function() {

	/*ask for user confirmation.*/
	var answer = confirm("Delete checked items?");
	
	/*if yes.*/
	if (answer) {
	
		var i = 0;
		
		/*remove every item from localStorage that has the data flag checked.*/
		while (i <= localStorage.length-1) {
		
     		var key = localStorage.key(i);
     		if (localStorage.getItem(key) === '1') {
     			localStorage.removeItem(key);
     		}
     		else { i++; }
     	}
     	/*update view.*/
     	checklistApp.getAllItems();
	}
	/*clear up.*/
	delete checklistApp.deleteChecked;
},

/*deletes all items in the list.*/
deleteAll: function() {

	/*ask for user confirmation.*/
	var answer = confirm("Delete all items?");
	
	/*if yes.*/
	if (answer) {
	
		/*remove all items from localStorage.*/
		localStorage.clear();
		/*update view.*/
   		checklistApp.getAllItems();
   }
   /*clear up.*/
   delete checklistApp.deleteAll;
},

/*Updates the mailto: list link.*/
updateMail: function() {

	/*clear the current mail link.*/
	document.querySelector('#maillink').href = '';
	
	var mail, subject, list, length;
	
	mail = 'mailto:?';
	subject = 'List';
	list = '';
	length = localStorage.length;
	
	/*go through every item in localStorage.*/
	if (length !== 0) {
	
		for (i = 0; i <= length-1; i++) {
		
			var key = localStorage.key(i);
			
			/*append to list if the item is not checked.*/
			if (localStorage.getItem(key) === '0') {
				list += localStorage.key(i) + '\n';
			}
		}
		
		/*if the processed list is not empty.*/
		if (list !== '') {
			
			/*update the mail link*/
			mail += 'subject=' + encodeURIComponent(subject);
			mail += '&body=' + encodeURIComponent(list);
			document.querySelector('#maillink').href = mail;
		}
	}
	/*clear up.*/
	delete checklistApp.updateMail;
},

/*displays the mail items button and calls updateMail().*/
sendMail: function() {

	/*get the number of unchecked items in the list.*/
	var remaining, maillist;
	
	remaining = document.querySelector('#remaining').innerHTML;
	maillist = document.querySelector('#maillist');
		
	/*if there are unchecked items.*/
   	if (remaining !== '0') {
   	
   		/*update the mail link.*/
   		checklistApp.updateMail();
   		
   		/*toggle the large mail link button.*/
   		if (maillist.style.display === 'none') {
   		   	maillist.style.display = 'block';
   		}
   		else {
   			maillist.style.display = 'none';
   	   	}
   	}
   	else {
   		alert("You have no items to mail!");
   	}
   	/*clear up.*/
   	delete checklistApp.sendMail;
},

/*stores user input on keyup.*/
storeInput: function() {

	/*store item temporarily in localStorage.*/
	localStorage.setItem('inputvalue', this.value);
	
  	/*clear up.*/
	delete checklistApp.storeInput;
}

};

/*function that runs once the document has loaded.*/
function loaded() {

	/*hide the address bar if visible in a browser such as Mobile Safari.*/
	window.scrollTo(0,0);
	
	/*check if the browser supports localStorage.*/
	if (typeof(localStorage) == 'undefined' ) {
		alert('Your browser does not support HTML5 localStorage. Try upgrading.');
	} 
	else {
	
		/*hide the mail list items button.*/
		document.querySelector('#maillist').style.display = 'none';
		
		/*display all existing saved items.*/
		checklistApp.getAllItems();
		
		/*run event delegation on the list.*/
		checklistApp.eventDelegation();
		
		/*stores user input in localStorage on keyup.*/ 
		document.querySelector('#name').addEventListener('keyup', checklistApp.storeInput, false);

		/*add an event listener for when the delete all items button is clicked.*/
		document.querySelector('#deleteall').addEventListener('click', checklistApp.deleteAll, false);

		/*add an event listener for when the delete checked items button is clicked.*/
		document.querySelector('#deletechecked').addEventListener('click', checklistApp.deleteChecked, false);

		/*add an event listener for when the mail button is clicked.*/
		document.querySelector('#sendmail').addEventListener('click', checklistApp.sendMail, false);

		/*add event listener for when the add button is clicked.*/
		document.querySelector('#add').addEventListener('click', checklistApp.addNewItem, false);
	}

}

window.addEventListener("load", loaded, true);

