// Dedicated object so we can deal with a separate dirty status, and thus
// call the endpoint only when needed, saving one call at each save.
L.U.MapPermissions = L.Class.extend({

    options: {
        owner: null,
        editors: [],
        share_status: null,
        edit_status: null
    },

    initialize: function (map) {
        this.options = map.options.permissions || {};
        this.map = map;
        var isDirty = false,
            self = this;
        try {
            Object.defineProperty(this, 'isDirty', {
                get: function () {
                    return isDirty;
                },
                set: function (status) {
                    isDirty = status;
                    if (status) self.map.isDirty = status;
                }
            });
        }
        catch (e) {
            // Certainly IE8, which has a limited version of defineProperty
        }

    },

    isOwner: function () {
        return this.map.options.user && this.options.owner && this.map.options.user.id == this.options.owner.id;
    },

    isAnonymousMap: function () {
        return !this.options.owner;
    },

    getMap: function () {
        return this.map;
    },

    edit: function () {
        if (!this.map.options.umap_id) return this.map.ui.alert({content: L._('Please save the map before'), level: 'info'});
        var container = L.DomUtil.create('div', 'permissions-panel'),
            fields = [],
            title = L.DomUtil.create('h4', '', container);
        if (this.isAnonymousMap()) {
            if (this.map.options.anonymous_edit_url) {
                var helpText = L._('Secret edit link is:<br>{link}', {link: this.map.options.anonymous_edit_url});
                fields.push(['options.edit_status', {handler: 'IntSelect', label: L._('Who can edit'), selectOptions: this.map.options.anonymous_edit_statuses, helpText: helpText}]);
            }
        } else {
            if (this.isOwner()) {
                fields.push(['options.edit_status', {handler: 'IntSelect', label: L._('Who can edit'), selectOptions: this.map.options.edit_statuses}]);
                fields.push(['options.share_status', {handler: 'IntSelect', label: L._('Who can view'), selectOptions: this.map.options.share_statuses}]);
                fields.push(['options.owner', {handler: 'ManageOwner', label: L._("Map's owner")}]);
            }
            fields.push(['options.editors', {handler: 'ManageEditors', label: L._("Map's editors")}]);
        }
        title.innerHTML = L._('Update permissions');
        var builder = new L.U.FormBuilder(this, fields);
        var form = builder.build();
        container.appendChild(form);
        if (this.isAnonymousMap() && this.map.options.user) {
            // We have a user, and this user has come through here, so they can edit the map, so let's allow to own the map.
            // Note: real check is made on the back office anyway.
            var advancedActions = L.DomUtil.createFieldset(container, L._('Advanced actions'));
            var advancedButtons = L.DomUtil.create('div', 'button-bar', advancedActions);
            var download = L.DomUtil.create('a', 'button', advancedButtons);
            download.href = '#';
            download.innerHTML = L._('Attach the map to my account');
            L.DomEvent
                .on(download, 'click', L.DomEvent.stop)
                .on(download, 'click', this.attach, this);
        }
        this.map.ui.openPanel({data: {html: container}, className: 'dark'});
    },

    attach: function () {
        this.map.post(this.getAttachUrl(), {
            callback: function () {
                this.options.owner = this.map.options.user;
                this.map.ui.alert({content: L._("Map has been attached to your account"), level: 'info'});
                this.map.ui.closePanel();
            },
            context: this
        })
    },

    save: function () {
        if (!this.isDirty) return this.map.continueSaving();
        var formData = new FormData();
        if (!this.isAnonymousMap() && this.options.editors) {
            var editors = this.options.editors.map(function (u) {return u.id});
            for (var i = 0; i < this.options.editors.length; i++) formData.append('editors', this.options.editors[i].id);
        }
        if (this.isOwner() || this.isAnonymousMap()) formData.append('edit_status', this.options.edit_status);
        if (this.isOwner()) {
            formData.append('owner', this.options.owner && this.options.owner.id);
            formData.append('share_status', this.options.share_status);
        }
        this.map.post(this.getUrl(), {
            data: formData,
            context: this,
            callback: function (data) {
                this.isDirty = false;
                this.map.continueSaving();
            }
        });
    },

    getUrl: function () {
        return L.Util.template(this.map.options.urls.map_update_permissions, {'map_id': this.map.options.umap_id});
    },

    getAttachUrl: function () {
        return L.Util.template(this.map.options.urls.map_attach_owner, {'map_id': this.map.options.umap_id});
    },

    addOwnerLink: function (element, container) {
        if (this.options.owner && this.options.owner.name && this.options.owner.url) {
            var ownerContainer = L.DomUtil.add(element, 'umap-map-owner', container, ' ' + L._('by') + ' '),
                owner = L.DomUtil.create('a');
            owner.href = this.options.owner.url;
            owner.innerHTML = this.options.owner.name;
            ownerContainer.appendChild(owner);
        }
    }

});
