/* 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);
                        }
                    }
                };
            }
        };
    }
}());
