coreFramework.directive('cfSharedModel', function ($parse) {
    return {
        restrict: 'A',
        require: ['ngModel', 'form', 'cfSharedModel'],
        link: function (scope, element, attrs, ctrl) {

            var ngModelCtrl = ctrl[0];
            var ngFormCtrl = ctrl[1];
            var cfSharedModelCtrl = ctrl[2];

            var name = {
                model: attrs.ngModel,
                errors: attrs.ngModel + 'Errors',
                shared: attrs.cfSharedModel,
                form: ngFormCtrl.$name
            };

            var ngModelGet = $parse(name.model);
            var ngModelSet = ngModelGet.assign;

            var ngModelErrorsGet = $parse(name.errors);
            var ngModelErrorsSet = ngModelErrorsGet.assign;

            var ngModelSharedGet = $parse(name.shared);
            var sharedModel = ngModelSharedGet(scope);
            var ngModelSharedSet = ngModelSharedGet.assign;
                ngModelSharedSet(scope, sharedModel);
            var ngForm;

            var watchers = {
                form: angular.noop,
                active: angular.noop,
                dirty: angular.noop,
                valid: angular.noop,
                model: angular.noop,
                state: angular.noop,
                errors: angular.noop
            };

            watchers.form = scope.$watch(name.form, function (value) {
                ngForm = value;
                watchers.form();
            });

            watchers.active = scope.$watch(name.shared + '.activeIndex', function () {
                // watchers.active();
                // return;
                watchers.dirty();
                watchers.valid();
                watchers.model();
                watchers.state();
                watchers.errors();

                watchers.model = sharedModel.activeModel.$watch('data', function (value) {
                    ngModelSet(scope, value);
                });

                watchers.errors = sharedModel.activeModel.$watch('dataErrors', function (value) {
                    ngModelErrorsSet(scope, value);
                });

                if (sharedModel.activeModel.form.is_dirty) {
                    ngFormCtrl.$setDirty();
                    ngForm && ngForm.$setDirty();
                } else {
                    ngFormCtrl.$setPristine();
                    ngForm && ngForm.$setPristine();
                }

                watchers.state = sharedModel.activeModel.$watch('state', function (value) {
                    if (sharedModel.activeModel.form.is_dirty) {
                        ngFormCtrl.$setDirty();
                        ngForm && ngForm.$setDirty();
                    } else {
                        ngFormCtrl.$setPristine();
                        ngForm && ngForm.$setPristine();
                    }
                });

                watchers.dirty = scope.$watch(function () {
                    return ngFormCtrl.$dirty;
                }, function (value) {
                    sharedModel.activeModel.form.is_dirty = value;
                });

                watchers.valid = scope.$watch(function () {
                    return ngFormCtrl.$valid;
                }, function (value) {
                    sharedModel.activeModel.form.is_valid = value;
                });

            });

            cfSharedModelCtrl.addSyncParam = function (param) {
                sharedModel.addSync(param);
            };

            cfSharedModelCtrl.addSkipParam = function (param) {
                sharedModel.addSkip(param);
            };



            var leaveMessage = 'You have unsaved data on this page.\nAre you sure you want to leave?';
            var getLeaveMessage = function () {
                var dirty = sharedModel.list.filter(function (item) {
                    return item.form.is_dirty;
                }).length;
                return dirty ? leaveMessage : null;
            };

            window.onbeforeunload = function () {
                return getLeaveMessage();
            };
            var leaveCheck = angular.noop;
            if (!skope.$root.$$listeners.$locationChangeStart || skope.$root.$$listeners.$locationChangeStart.filter(function (item) { return item.name == 'onbeforeunload'; }).length == 0) {
                leaveCheck = scope.$root.$on('$locationChangeStart', function onbeforeunload (e) {
                    var msg = getLeaveMessage();
                    if(msg && !confirm(msg)) {
                        e.preventDefault();
                    }
                });
            }
            scope.$on('$destroy', function () {
                window.onbeforeunload = null;
                leaveCheck();
            });


        },
        controller: ['$scope', function($scope) {

        }]
    };
});
coreFramework.directive('cfSharedModelWrapper', function () {
    return {
        restrict: 'A',
        require: ['ngModel', 'cfSharedModel'],
        scope: true,
        link: function (scope, element, attrs, ctrl) {

            var watcher = scope.$watch(attrs.cfSharedModel + '.activeModel.data', function (value) {
                scope.data = value;
                // watcher();
            });

        }
    };
});
coreFramework.directive('cfSharedModelSync', function ($timeout) {
    return {
        restrict: 'A',
        require: ['ngModel', '^cfSharedModel'],
        link: function (scope, element, attrs, ctrl) {

            var cfSharedModelCtrl = ctrl[1];

            $timeout(function () {

                var modelName;
                if (attrs.cfSharedModelSync) {
                    modelName = attrs.cfSharedModelSync;
                } else {
                    modelName = element.parentsUntil('[cf-shared-model]', '[ng-model]').toArray().map(function (item) {
                        return angular.element(item).attr('ng-model');
                    }).reverse().concat([attrs.ngModel]).map(function (item) {
                        return item.replace(/^data\./i, '');
                    }).join('\.');
                }

                cfSharedModelCtrl.addSyncParam(modelName);

            });

        }
    };
});
coreFramework.directive('cfSharedModelSkip', function ($timeout) {
    return {
        restrict: 'A',
        require: ['ngModel', '^cfSharedModel'],
        link: function (scope, element, attrs, ctrl) {

            var cfSharedModelCtrl = ctrl[1];

            $timeout(function () {

                var modelName = element.parentsUntil('[cf-shared-model]', '[ng-model]').toArray().map(function (item) {
                    return angular.element(item).attr('ng-model');
                }).reverse().concat([attrs.ngModel]).map(function (item) {
                    return item.replace(/^data\./i, '');
                }).join('\.');

                cfSharedModelCtrl.addSkipParam(modelName);

            });

        }
    };
});
coreFramework.directive('cfSharedModelTabs', function ($animate) {
    return {
        restrict: 'A',
        scope: true,
        replace: true,
        template:   '<nav class="Tabs-header" role="navigation">' +
                        '<ul class="Tabs-list u-cf g-container">' +
                            '<li class="Tabs-item" ng-repeat="item in model.list" ng-class="{ \'is-active\': model.activeIndex == $index }">' +
                                '<a class="Tabs-link" ng-href="#" ng-click="model.activeIndex = $index;">' +
                                    '{{ item.language.id }}' +
                                    '<span ng-if="item.state != \'pristine\'" class="icon-status fa" ng-style="{ color: item.state == \'error\' ? \'red\' : \'\' }" ng-class="classes[item.state]"></span>' +
                                '</a>' +
                                // '<a class="Tabs-switch Widget-visibilityAction" ng-class="{ \'is-hidden\': !item.data.is_active }" ng-click="item.data.is_active = !item.data.is_active;">' +
                                //     '<span class="u-isHiddenVisually">active</span>' +
                                // '</a>' +
                            '</li>' +
                        '</ul>' +
                        // '<div>' +
                        //     '<button ng-click="model.copyFrom(languageSelected)" ng-disabled="model.activeIndex == languageSelected">Copy from</button>' +
                        //     '<select ng-model="languageSelected" ng-change="model.copyFrom(languageSelected)">' +
                        //         '<option ng-repeat="item in model.list" ng-disabled="model.activeIndex == $index" value="{{ $index }}">' +
                        //             '{{ item.language.title }}' +
                        //         '</option>' +
                        //     '</select>' +
                        // '</div>' +
                        // '<div ng-repeat="item in model.list">' +
                        //     '{{ item.language.id }} {{ item.state }}' +
                        // '</div>' +
                    '</nav>',
        link: function (scope, element, attrs, ctrl) {

            $animate.enabled(false, element);

            var watcher = scope.$watch(attrs.cfSharedModelTabs, function (value) {
                scope.model = value;
                scope.languageSelected = 0;
                watcher();
            });

            scope.classes = {
                pristine: '',
                dirty: 'fa-circle-o',
                error: 'fa-exclamation-circle',
                loading: 'fa-refresh fa-spin'
            };

        }
    };
});
coreFramework.directive('cfSharedModelActions', function () {
    return {
        restrict: 'A',
        scope: true,
        replace: true,
        template:   '<div ng-class="\'Tabs-content Tabs-contentHeader TabsHeader\'">' +
                        '<span class="TabsHeader-title">' +
                            '{{ model.activeModel.language.title }} translation' +
                        '</span>' +
                        '<span class="TabsHeader-switch" ng-show="isActiveSwitch()">' +
                            '<a class="Widget-visibilityAction" ng-class="{ \'is-hidden\': !model.activeModel.data.is_active }" ng-click="model.activeModel.data.is_active = !model.activeModel.data.is_active;">visible</a>' +
                        '</span>' +
                        '<div class="Tabs-actions" ng-show="copyFrom">' +
                            '<span class="Tabs-actionsLink">' +
                                '<i class="fa fa-ellipsis-v"></i>' +
                            '</span>' +
                            '<div class="Tabs-dropdown" tabindex="-1" ng-class="{ \'is-open\': copyFromOpened }">' +
                                '<a ng-repeat="item in model.list" ng-click="copyFromClose(); model.copyFrom($index);" href="#">Copy from {{ item.language.id }}</a>' +
                            '</div>' +
                        '</div>' +
                    '</div>',
        link: function (scope, element, attrs, ctrl) {

            var watcher = scope.$watch(attrs.cfSharedModelActions, function (value) {
                scope.model = value;
                watcher();
            });

            scope.isActiveSwitch = function () {
                return angular.isDefined(scope.$eval('model.activeModel.data.is_active'));
            };

            scope.copyFrom = attrs.copyFrom ? scope.$eval(attrs.copyFrom) : true;
            scope.copyFromOpened = false;
            scope.copyFromClose = function () {
                scope.copyFromOpened = false;
            };

            element.find('.Tabs-actionsLink').click(function (e) {
                e.preventDefault();
                element.find('.Tabs-dropdown').focus();
                scope.$apply(function () {
                    scope.copyFromOpened = true;
                });
            });
            element.find('.Tabs-dropdown').on('blur', function () {
                scope.$apply(function () {
                    scope.copyFromOpened = false;
                });
            }).on('mousedown', function (e) {
                e.preventDefault();
            });

        }
    };
});
