var crmApp = angular.module("crmApp", [
    'datatables',
    'ngAnimate',
    'ngSanitize',
    'ngMaterial',
    //'chart.js',
    'angular-timeline',
    'ngMaterial',
    'ngRoute',
    'ngMessages',
    'ui.select',
    //'720kb.datepicker',
    'ngFileUpload',
    'LocalStorageModule',
    'localytics.directives',
	'ui.calendar',
    //Added for datetimepicker
    'ui.bootstrap',
    'ui.bootstrap.datetimepicker',

]);
angular.module('crmApp').filter('numberNoSeperator', function ($filter) {
    return function (number, pre) {
        return parseInt(number);
    };
});

crmApp.filter('hideUndefined', function () {
    return function (items) {
        var filtered_items = [];

        //iterate over all emails
        for (var i = 0; i < items.length; i++) {
            //if not undefined, add to filtered_items array
            if (items[i].FieldMappingID !== undefined && items[i].FieldMappingID != 0) {
                filtered_items.push(items[i])
            }
        }
        return filtered_items;
    }
})
crmApp.directive('currencyInput', function ($filter, $browser) {
    return {
        require: 'ngModel',
        link: function ($scope, $element, $attrs, ngModelCtrl, GeneralService) {
            var listener = function () {
                var value = $element.val().replace(/,/g, '');
                console.log('listener value : ', value);
                $element.val($filter('number')(value, 2));
                console.log('listener value 2 : ', value);
            }
            function getFormattedNumber(number) {
                var result = "";
                var numberWithoutComma = number.replace(/\,/g, "");

                if (numberWithoutComma)
                    return $filter('number')(numberWithoutComma, 2);
                return result;
            }

            var onBlurEvent = function () {
                var value = $element.val();
                var newValue = getFormattedNumber(value);
                $element.val(newValue);
            }

            // This runs when we update the text field
            ngModelCtrl.$parsers.push(function (viewValue) {
                return viewValue.replace(/,/g, '');
            })

            // This runs when the model gets updated on the scope directly and keeps our view in sync
            ngModelCtrl.$render = function () {
                var value = '';
                if (ngModelCtrl.$viewValue) {
                    var numberWithoutComma = ngModelCtrl.$viewValue.replace(/\,/g, "");
                    if (numberWithoutComma)
                        value =  $filter('number')(numberWithoutComma, 2);
                }
                    //var value = $filter('number')(ngModelCtrl.$viewValue, false);
                $element.val(value);
            }

            //$element.bind('change', listener)
            $element.bind('blur', function (event) {
                var value = $element.val();
                var newValue = getFormattedNumber(value);
                $element.val(newValue);
            });
            $element.bind('keydown', function (event) {
                var key = event.keyCode
                // If the keys include the CTRL, SHIFT, ALT, or META keys, or the arrow keys, do nothing.
                // This lets us support copy and paste too
                if (key == 91 || (15 < key && key < 19) || (37 <= key && key <= 40) || (188 <= key && key <= 190))
                    return
                //$browser.defer(onBlurEvent) // Have to do this or changes don't get picked up properly
            })

            $element.bind('paste cut', function () {
                // $browser.defer(listener)
            })
        }

    }
})

function getFormattedNumber($filter, number) {
    var result = "";
    var numberWithoutComma = number.replace(/\,/g, "");

    if (numberWithoutComma)
        return $filter('number')(numberWithoutComma, 2);
    return result;
}
/**
 * Update a $scope variable when user is in an input 
 * field and presses enter
 * <input ng-enter="giftTotal"/>
 */
crmApp.directive('inputMoney', function () {
    return function (scope, element, attrs) {
        element.bind("keydown keypress", function (event) {
            if (event.which >= 48 && event.which <= 57 || event.which == 44 || event.which == 46) {
                scope.$apply(function () {
                    scope[attrs.inputMoney] = element.val();
                });

                //event.preventDefault();
            }
            else { return false; }
        });
    };
});
//window.onbeforeunload = function () {
//    localStorage.removeItem("crmApp.UserInfo");

//};

crmApp.factory('sessionInjector', ['AntiForgeryService', function (AntiForgeryService) {
    var sessionInjector = {
        request: function (config) {
            config.headers['RequestVerificationToken'] = AntiForgeryService.cookieToken + ":" + AntiForgeryService.formToken;

            return config;
        }
    };
    return sessionInjector;
}]);

function GetDemoUser() {
    var ua = window.navigator.userAgent;
    var userID = 'lhdn\kaunterofficer1';

    //if ($browser.mozilla) {
    //    if (ua.indexOf('Edge') > 0)
    //        userID = 'lhdn\kaunterofficer1';
    //    else
    //        userID = 'lhdn\HCLAgent';
    //}
    //else if ($browser.safari) {
    //    userID = 'lhdn\AMSGKetuaUnit';
    //}
    //else if ($browser.msie)
    //{
    //    userID = 'lhdn\AMSGOfficer';
    //}

    if (navigator.userAgent.search("MSIE") >= 0) {
        // insert conditional IE code here
        userID = 'lhdn\\AMSGOfficer';
    }
        //Check if browser is Chrome
    else if (navigator.userAgent.search("Chrome") >= 0) {
        // insert conditional Chrome code here
        if (ua.indexOf('Edge') > 0)
            userID = 'lhdn\\kaunterofficer1';
        else
            userID = 'lhdn\\HCLAgent';
    }
        //Check if browser is Firefox 
    else if (navigator.userAgent.search("Firefox") >= 0) {
        // insert conditional Firefox Code here
        userID = 'lhdn\\AMSGKetuaUnit';
    }

    return userID;
}

crmApp.factory('errorHandler', ['$q', function ($q) {
    var updateConflict = "UpdateConflict";
    var routeToAgentException = "RouteToAgent";
    var refreshPageMsg = "Update conflict! Please refresh the page to proceed.";
    var systemErrorMsg = 'Sila hubungi Pentadbir Sistem.';
    return {
        responseError: function (rejection) {
            if (rejection.status == 401 || rejection.status == 403 || rejection.status == 405) // Access Denied
                $.redirect('/Error/AccessDenied?mode=app', {
                    'msg': rejection.data.Message
                });
            else if (rejection.status == 404) // Not Found
                $.redirect('/Error/NotFound', {
                    'msg': rejection.data
                });
            else if (rejection.data == updateConflict) {
                swal("Failed", refreshPageMsg, "error");
                console.log(rejection);
            }
            else if (rejection.data == routeToAgentException) {
                swal("Gagal!", "This activity is not allowed to route to HCL.", "error");
                console.log(rejection);
            }
            else {
                swal("Gagal!", systemErrorMsg, "error");
                console.log(rejection);
            }
            console.log(rejection);
            return $q.reject(rejection);
        }
    };
}]);

crmApp.factory('uPTimeStampHandler', ['$rootScope', 'localStorageService', function ($rootScope, localStorageService) {
    //User Profile TimeStamp
    return {
        response: function (response) {
            var up_timestamp = decodeURIComponent(getCookie("up_timestamp"));
            //console.log("Cookie timestamp")
            //console.log(up_timestamp);
            (localStorage.getItem("crmApp.UserInfo") || console.log(localStorage.getItem("crmApp.UserInfo"))) && console.log("LS timestamp") && console.log(localStorageService.get("UserInfo").UP_TimeStamp);

            if (localStorageService.get("UserInfo") != null && localStorageService.get("UserInfo").UP_TimeStamp != up_timestamp) {
                //Clear
                console.log("Clear LS")
                localStorage.removeItem("crmApp.UserInfo");
                console.log("getUsrInfoEvt call event")
                $rootScope.$broadcast('getUsrInfoEvt')
            }
            return response;
        }
    };
}]);


function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') c = c.substring(1);
        if (c.indexOf(name) != -1) return c.substring(name.length, c.length);
    }
    return "";
}

crmApp.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.interceptors.push('sessionInjector');
    $httpProvider.interceptors.push('errorHandler');
    $httpProvider.interceptors.push('uPTimeStampHandler');
}]);

crmApp.config(function (localStorageServiceProvider) {
    localStorageServiceProvider.setPrefix("crmApp");
});

crmApp.config(['chosenProvider', function (chosenProvider) {
    chosenProvider.setOption({
        placeholder_text_single: 'Sila pilih satu',
        disable_search_threshold: '5'
    });
}]);

crmApp.run(function (DTDefaultOptions, $compile) {
    DTDefaultOptions.setOption('sDom', '<"top"li>rt<"bottom"p><"clear">');

    DTDefaultOptions.setOption('lengthChange', true);

    DTDefaultOptions.setOption('order', []);

    DTDefaultOptions.setOption("language", {
        "sLengthMenu": "<select class='form-control'>" +
            "<option value='10'>Papar 10 rekod</option>" +
            "<option value='25'>Papar 25 rekod</option>" +
            "<option value='50'>Papar 50 rekod</option>" +
            "<option value='100'>Papar 100 rekod</option>" +
            "</select>",
        "zeroRecords": "Maaf. Tiada rekod untuk dipaparkan",
        "info": "<div class='dt-info-content'><b>Jumlah rekod: _TOTAL_</b> | Papar _START_-_END_ (Muka _PAGE_ dari _PAGES_)</div>",
        "infoEmpty": "Tiada Rekod",
        "infoFiltered": "",
        "emptyTable": "Tiada Rekod",
        "oPaginate": {
            "sFirst": "<i class='fa fa-angle-double-left'></i>",
            "sLast": "<i class='fa fa-angle-double-right'></i>",
            "sNext": "<i class='fa fa-angle-right'></i>",
            "sPrevious": "<i class='fa fa-angle-left'></i>"
        },
        "sProcessing": '<div style="background-color:#f4f4f4;border:#ddd solid 1px;"><i class="fa fa-spin fa-refresh black"></i> <span style="color:black !important;font-weight:bold;">&nbsp; Retrieving data....</span></div>'
    });


    $.fn.dataTable.ext.errMode = function (settings, tn, msg) {
        console.dir(msg);
    }

    Array.prototype.clean = function (deleteValue) {
        for (var i = this.length - 1 ; i >= 0 ; i--) {
            if (this[i] == deleteValue) {
                this.splice(i, 1);
            }
        }
        return this;
    };
});

crmApp.directive('clickAndDisable', function () {
    return {
        scope: {
            clickAndDisable: '&'
        },
        link: function (scope, elem, attrs) {
            elem.bind('click', function () {
                elem.prop('disabled', true);
                scope.clickAndDisable().finally(function () {
                    elem.prop('disabled', false);
                })
            });
        }
    };
});
//crmApp.directive('clickAndDisable', function ($parse, $q, $timeout) {
//    var link = function (scope, elem, attr) {
//        var isNotifyMode = attr.clickAndDisable.indexOf('$notify') > -1;
//        var fn = $parse(attr.clickAndDisable, null, true);
//        var previousText = elem.text();

//        var disableBtn = function () {
//            elem.text('wait...');
//            elem.attr('disabled', 'disabled');
//        };
//        var enableBtn = function () {
//            elem.text(previousText);
//            elem.attr('disabled', '');
//        };

//        elem.on('click', function (event) {
//            scope.$apply(function () {
//                if (isNotifyMode) {
//                    disableBtn();
//                }
//                fn(scope, {
//                    $event: event,
//                    $notify: function () {
//                        enableBtn();
//                    }
//                });
//            });
//        });

//    };
//    return {
//        link: link,
//        restict: 'A',
//    };
//});
crmApp.directive('clickAndInvoke', function () {
    return {
        scope: {
            'docSelector': '@',
            'sibSelector': '@'
        },
        link: function (scope, elem, attrs) {
            var s = attrs.selector;
            var el = null;

            if (s) {
                el = elem[0].querySelector('.' + s);
            }
            else if (scope.sibSelector) {
                s = scope.sibSelector;
                el = angular.element(elem[0]).siblings('.' + s);
            }
            else if (scope.docSelector) {
                s = scope.docSelector;
                el = angular.element(document.querySelector(s));
            }
            else
                return;

            elem.bind('click', function () {
                angular.element(el)[0].focus();
                angular.element(el)[0].click();
            });
        }
    };
});

crmApp.directive('uncheckRadioBtn', function () {

    return {
        scope: {
            ngModel: '='
        },
        link: function link(scope, element, attrs) {
            element.bind('click', function ($event) {
                console.log(angular.element(element[0]).prop('checked'));
                console.log(element[0]);
                if (element[0].value != $event.target.value) {
                    element[0].checked = false;

                    angular.element(element[0]).trigger('change');
                }
            });
        }
    };
});

crmApp.filter('unique', function () {

    return function (items, filterOn) {


        if (filterOn === false) {
            return items;
        }

        if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
            var hashCheck = {}, newItems = [];

            var extractValueToCompare = function (item) {
                if (angular.isObject(item) && angular.isString(filterOn)) {
                    return item[filterOn];
                } else {
                    return item;
                }
            };

            angular.forEach(items, function (item) {
                var valueToCheck, isDuplicate = false;

                for (var i = 0; i < newItems.length; i++) {
                    if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
                        isDuplicate = true;
                        break;
                    }
                }
                if (!isDuplicate) {
                    newItems.push(item);
                }

            });
            items = newItems;
        }
        return items;
    };
});

angular.module('directive.loading', [])

crmApp.directive('loading', ['$http', function ($http) {
    return {
        restrict: 'A',
        link: function (scope, elm, attrs) {
            scope.isLoading = function () {
                return $http.pendingRequests.length > 0;
            };

            scope.$watch(scope.isLoading, function (v) {
                if (v) {
                    elm.show();
                } else {
                    elm.hide();
                }
            });
        }
    };

}]);

angular.module("crmApp  ", [])

//inspired by http://jsfiddle.net/dZDLg/46/


crmApp.directive("disableWithAttr", function ($parse) {

    console.log("Disable Options Directive Called");

    var disableOptions = function (scope, attr, element, data, fnDisableIfTrue) {
        // refresh disabled  options in the select element.
        angular.forEach(element.find("option"), function (value, index) {
            var elem = angular.element(value);
            if (elem.val() != "") {
                var locals = {};
                locals[attr] = data[index];
                elem.attr("disabled", fnDisableIfTrue(scope, locals));
            }
        });
    };
    return {
        priority: 0,
        require: 'ngModel',
        link: function (scope, iElement, iAttrs, ctrl) {

            // parse the expression and build array of disabled options
            var expElements = iAttrs.disableWithAttr.match(/^\s*(.+)\s+for\s+(.+)\s+in\s+(.+)?\s*/);
            var attrToWatch = expElements[3];
            var fnDisableIfTrue = $parse(expElements[1]);

            // Register Watch
            scope.$watch(attrToWatch, function (newVal, oldVal) {
                if (newVal) {
                    disableOptions(scope, expElements[2], iElement, newVal, fnDisableIfTrue);
                }
            }, true);

            // Register Watch
            scope.$watch(iAttrs.ngModel, function (newVal, oldVal) {
                var disOptions = $parse(attrToWatch)(scope);
                if (newVal) {
                    disableOptions(scope, expElements[2], iElement, disOptions, fnDisableIfTrue);
                }
            });
        }
    };
})
