ProspectDirector.Modules.Security.AclControl = Class.extend({

    //===================================
    // FIELDS
    //===================================

    _aclGrid: null,
    _aceGrid: null,
    _effectivePermissionsState: null,

    //===================================
    // CONSTRUCTOR
    //===================================

    init: function (options) {
        
        this.options = $.extend({
            selector: null,
            containerSelector: null,
            aceData: [],
            permissionData: [],
            securableId: null,
            enabled: true,
            hasChanges: false,
            userDisplayName: null
        }, options);

        this.aceGrid_init();
        this.aclGrid_init();

        this.get_addButton().on("click", $.proxy(this.addButton_onClick, this));
        this.get_removeButton().on("click", $.proxy(this.removeButton_onClick, this));
        this.get_advancedButton().on("click", $.proxy(this.advancedButton_onClick, this));
        this.get_effectivePermissionsButton().on("click", $.proxy(this.effectivePermissionsButton_onClick, this));
        
        this.get_container().disableTextSelection();

        this.get_container().data("aclControl", this);

        //SECURITY FIX HACK

        var parentElement = $("INPUT[data-id=INJECTED\\:PARENT]");

        if (parentElement.length > 0) {
            parentElement.on("change", _.bind(this.entityParent_onChange, this));
        }

        this._effectivePermissionsState = {
            securableId: this.options.securableId,
            identity: {
                id: PD.ENVIRONMENT.USER_ID,
                displayName: this.options.userDisplayName
            },
            acl: []
        }

        //SECURITY FIX HACK

        this.commit();

    },

    //===================================
    // PROPERTIES
    //===================================
    
    get_container: function () {
        return $(this.options.selector);
    },

    get_aclGridContainer: function () {
        return this.get_container().find("DIV[data-role=acl-grid-container]");
    },

    get_aceGridContainer: function () {
        return this.get_container().find("DIV[data-role=ace-grid-container]");
    },

    get_addButton: function () {
        return this.get_container().find("INPUT[type=button][data-command=add]");
    },

    get_removeButton: function () {
        return this.get_container().find("INPUT[type=button][data-command=remove]");
    },

    get_advancedButton: function () {
        return this.get_container().find("INPUT[type=button][data-command=advanced]");
    },

    get_effectivePermissionsButton: function () {
        return this.get_container().find("INPUT[type=button][data-command=effective-permissions]");
    },

    get_aclStore: function () {
        return this.get_container().find("INPUT[data-id=acl-data]");
    },
    
    //===================================
    // INITIALIZERS
    //===================================

    aclGrid_init: function () {

        this._aclGrid = new PD.Web.UI.Controls.Security.AclEditor({
            container: this.get_aclGridContainer(),
            aces: this.options.aceData,
            change: _.bind(this.aclGrid_onChange, this)
        });

    },

    aceGrid_init: function () {

        this._aceGrid = new PD.Web.UI.Controls.Security.AceEditor({
            container: this.get_aceGridContainer(),
            permissions: this.options.permissionData,
            change: _.bind(this.aceGrid_onChange, this)
        });

    },
    
    //===================================
    // EVENT HANDLERS
    //===================================

    addButton_onClick: function (e) {
        this._aclGrid.addAce();
    },

    removeButton_onClick: function (e) {
        this._aclGrid.removeAce();
    },

    advancedButton_onClick: function (e) {

        ProspectDirector.Modules.Security.AclAdvancedDialog.Dialog.show({
            params: {
                id: this.options.securableId,
                hasChanges: this.options.hasChanges
            }
        });

    },

    effectivePermissionsButton_onClick: function (e) {

        var that = this;

        PD.Shared.Dialogs.EffectivePermissions.open({
            entityId: this._effectivePermissionsState.securableId,
            identity: this._effectivePermissionsState.identity,
            acl: this._aclGrid.getAcl(),
            callbacks: {
                close: function (sender, e) {
                    if (e.identity != null) {
                        that._effectivePermissionsState.identity = e.identity;
                    }
                }
            }
        });

    },
    
    entityParent_onChange: function (e) {
        
        var aclGrid = this._aclGrid;

        var $entityTypeId = $("DIV[data-id=entity-create-form] > INPUT[data-role=entity-type-id]");
        var entityTypeId = null;

        var $entityParentId = $("INPUT[data-id=INJECTED\\:PARENT]");
        var entityParentId = null;

        if ($entityTypeId.length > 0) {
            entityTypeId = parseInt($entityTypeId.val());
        }

        if ($entityParentId.length > 0) {
            entityParentId = parseInt($entityParentId.val());
        }

        PD.ajax({
            url: PD.Path.resolve("~/Entity/GetSecurity"),
            data: {
                id: entityTypeId,
                parentId: entityParentId
            },
            success: function (e) {
                if (e.acl !== null && e.acl.aces !== null) {
                    aclGrid.addAce(e.acl.aces);
                }
            }
        });

    },

    aclGrid_onChange: function (e) {
        this._aceGrid.loadAce(e);
        this.commit();
    },

    aceGrid_onChange: function (e) {
        this._aclGrid.updateAce(e);
        this.commit();
    },

    //===================================
    // METHODS
    //===================================

    getAcl: function() {
        return this._aclGrid.getAcl();
    },

    commit: function () {
        var aclData = null;
        if (this._aclGrid != null) {
            aclData = this._aclGrid.getAcl();
            this.get_aclStore().val(JSON.stringify(aclData));
        }
    }

});