/* usage example first occurance is tristate, second occurance is normal checkbox.

				<div ng-repeat="person in vm.model.people" class="person">
					test
					<label>
						<tic-checkbox child-list="person.fruits" child-boolean-property="eaten" ng-model="person.allEaten"> {{person.name}} [All eaten: {{person.allEaten}}]
						</tic-checkbox>
					</label>
					<div ng-repeat="fruit in person.fruits" class="child-list">
						<label>
							<tic-checkbox ng-model="fruit.eaten"> {{fruit.type}} : {{fruit.eaten}} </tic-checkbox>
						</label>
					</div>
				</div>
*/


(function() {

	'use strict';

	angular.module('ti_common').directive('ticCheckbox', checkbox);
	checkbox.$inject = [];

	function checkbox() {
		return {
			restrict: 'E',
			scope: true,
			require: 'ngModel',
			compile: function(element) {
				var htmlText = '<span class="tic-check-box"><i class="material-icons {{getClass()}}">{{getIcon()}}</i>' + element.html() + '</span>';
				element.replaceWith(htmlText);

				return {
					pre: function() {},
					post: function(scope, element, attrs, modelCtrl) {
						var childList = attrs.childList;
						var property = attrs.childBooleanProperty;
						var list = scope.$eval(childList);

						scope.getClass = function() {
							var isIndeterminate = element.prop('indeterminate');
							if (!isIndeterminate) {
								var isChecked = element.prop('checked');
								if (!isChecked) {
									return 'tic-unchecked';
								}
							}

							return '';
						};

						scope.getIcon = function() {
							var isIndeterminate = element.prop('indeterminate');
							if (isIndeterminate) {
								return 'indeterminate_check_box'; //&#xE909;
							} else {
								var isChecked = element.prop('checked'); //&#xE834;
								if (isChecked) {
									return 'check_box';
								} else {
									return 'check_box_outline_blank'; //&#xE835;
								}
							}
						};

						// Bind the onChange event to update children
						element.bind('click', function() {
							scope.$apply(function() {
								var isChecked = element.prop('checked');

								isChecked = !isChecked;
								element.prop('checked', isChecked);
								modelCtrl.$setViewValue(isChecked);

								// Set each child's selected property to the checkbox's checked property
								if (childList) {
									angular.forEach(list, function(child) {
										child[property] = isChecked;
									});
								}
							});
						});

						function numberOfCheckedChild() {
							var checkedCount = 0;
							angular.forEach(list, function(child) {
								if (child[property]) {
									checkedCount++;
								}
							});
							return checkedCount;
						}

						// Watch the children for changes, also init by design
						if (childList) {
							scope.$watch(numberOfCheckedChild, function(newValue) {
		
								// Determine which state to put the checkbox in
								if (newValue > 0 && newValue < list.length) {
									element.prop('checked', false);
									element.prop('indeterminate', true);
									if (modelCtrl) {
										modelCtrl.$setViewValue(false);
									}
								} else {
									var isChecked = (newValue === 0) ? false : true;
									element.prop('checked', isChecked);
									element.prop('indeterminate', false);
									if (modelCtrl) {
										modelCtrl.$setViewValue(isChecked);
									}
								}
							});
						} else {
							scope.$watch(function() {
								return modelCtrl.$modelValue;
							}, function() {
								var isChecked = modelCtrl.$viewValue;

								element.prop('checked', isChecked);
								element.prop('indeterminate', false);

								if (modelCtrl) {
									modelCtrl.$setViewValue(isChecked);
								}

							}, true);
						}
					}
				};
			}
		};
	}

}());
