/// class ProspectDirector.Web.UI.FeatureSets.TargetEditorDialog
/// using ProspectDirector.Web.UI.Dialog

/**
@class TargetEditorDialog
@namespace Web.UI.FeatureSets
@constructor
@extends Web.UI.Dialog
**/
ProspectDirector.Web.UI.FeatureSets.TargetEditorDialog = ProspectDirector.Web.UI.Dialog.extend({

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

    _layout: null,
    _featureSet: null,
    _DOM: null,
    _isRequesting: false,

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

    init: function (options) {
        
        this.options = $.extend(true, {
            markup: "",
            showLoadingMessage: false,
            config: {
                actions: ["maximize", "close"],
                modal: true,
                iframe: false,
                resizable: true,
                height: 550,
                width: 700,
                minHeight: 300,
                minWidth: 400
            }
        }, options);

        this._super(this.options);

        this.get_eventBus().subscribe("dialog-add-deck-item", $.proxy(this._addDeckItem, this));
        this.get_eventBus().subscribe("reload-target", $.proxy(function (e, param) {
            this._reload(param);
        }, this));

        this._load();

    },

    //================================
    // PROPERTIES
    //================================

    /**
    @property get_data {Object}
    **/
    get_data: function () {
        return this.get_featureSet().get_data();
    },

    /**
    @property get_featureSet {Object}
    **/
    get_featureSet: function () {
        return this._featureSet;
    },

    /**
    @property get_layout {ProspectDirector.Web.UI.FeatureSets.TargetEditorLayout}
    */
    get_layout: function () {
        return this._layout;
    },

    /**
    @property get_options {Object}
    **/
    get_options: function () {
        return this.options;
    },

    //================================
    // PROTECTED METHODS
    //================================

    _activate: function () {
        this.DOM().activate();
        this.get_layout().activate();
    },

    _cancel: function (e) {
        this.hide();
    },

    _commit: function (e) {

        this.get_featureSet().commit();

        this._requestMonitorStart();

        PD.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: ProspectDirector.RUNTIME.resolveUrl("~/Target/Save"),
            data: JSON.stringify(this.get_featureSet().get_data().context),
            success: $.proxy(this._commitSuccess, this),
            error: $.proxy(this._commitError, this)
        });

    },

    _commitError: function (e) {

        //This method has been specialized specifically for feature set error handling.

        this._requestMonitorStop();

        if (e.responseJSON !== null && _.isArray(e.responseJSON)) {
            e.responseJSON = {
                errors: e.responseJSON
            };
        }

        var handler = new ProspectDirector.Web.UI.FeatureSets.ValidationErrorHandler({
            validationErrors: e.responseJSON.errors,
            featureSet: this.get_featureSet(),
            eventBus: this.get_eventBus()
        });

        handler.exec();

        //Added so the underlying default error handler will pick up any remianing error handling.
        e.responseJSON = e.responseJSON.errors;

    },

    _commitSuccess: function (e) {

        this._requestMonitorStop();

        this.hide({
            command: "ok",
            data: e
        });

    },

    _getArbiter: function () {
        return null;
    },

    _load: function () {

        var that = this;

        this._requestMonitorStart();

        PD.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: ProspectDirector.RUNTIME.resolveUrl("~/Target/Edit"),
            data: JSON.stringify(this._getArbiter()),
            success: $.proxy(this._loadSuccess, this),
            error: function (e) {
                that.hide();
            }
        });

    },

    _loadSuccess: function (e) {

        var that = this;
        var featureSet = null;

        this._requestMonitorStop();

        e = $.extend(true, e, {
            eventBus: this.get_eventBus()
        });

        _.each(e.context.messages, function (item) {
            if (item.tags.hasOwnProperty("dialogTitle")) {
                that.setOptions({
                    title: item.tags["dialogTitle"]
                });
            }
        });
        
        featureSet = new ProspectDirector.Web.UI.FeatureSets.FeatureSet(e);

        this._loadLayout(featureSet);
        
        this.get_featureSet().on("refresh", _.bind(function () {
            that._reload(false);
        }, this));

    },

    _reload: function (withValidation) {

        var that = this,
            url = !withValidation ? "~/Target/RefreshNoValidation?NoValidate=1" : "~/Target/Refresh";

        this.get_featureSet().commit();

        this._requestMonitorStart();

        PD.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: ProspectDirector.RUNTIME.resolveUrl(url),
            data: JSON.stringify(that.get_featureSet().get_data().context),
            success: $.proxy(that._loadSuccess, that),
            error: $.proxy(that._commitError, that)
        });

    },

    _render: function () {
        var content = this.get_layout().render();
        this.DOM().render(content);
    },

    //================================
    // OVERIDDEN METHODS
    //================================

    _resize: function (e) {

        if (this.get_layout()) {
            this.get_layout().resize(e);
        }

    },

    //================================
    // PUBLIC METHODS
    //================================

    DOM: function () {

        if (!this._DOM) {
            this._DOM = new ProspectDirector.Web.UI.FeatureSets.TargetEditorDialogDOM({
                id: this.get_window().get_id(),
                commit: $.proxy(this._commit, this),
                cancel: $.proxy(this._cancel, this)
            });
        }

        return this._DOM;

    },

    //================================
    // PRIVATE METHODS
    //================================

    _addDeckItem: function (e, item) {
        this.DOM().addDeckItem(item);
    },

    _loadLayout: function (featureSet) {

        var layoutType = this.get_options().data.layoutType,
            groupId = null;

        if (layoutType === null || layoutType === undefined) {
            layoutType = ProspectDirector.Web.UI.FeatureSets.Layouts.SideBarLayout;
        }

        this._featureSet = featureSet;

        if (this.get_layout()) {
            groupId = this.get_layout().getSelectedGroupId();
            this.get_layout().destroy();
        }

        this._layout = new layoutType({
            containerId: this.get_window().get_id(),
            parent: this,
            featureSet: featureSet,
            eventBus: this.get_eventBus(),
            groupId: groupId
        });

        this._render();
        this._activate();

        this.get_window().resize();

    },

    _requestMonitorStart: function () {

        var that = this;

        this._isRequesting = true;

        setTimeout(function () {
            if (that._isRequesting) {
                that.DOM().block();
            }                   
        }, 1500);

    },

    _requestMonitorStop: function () {
        this._isRequesting = false;
        this.DOM().unblock();
    },

    _abort: function (message) {

        this.hide();

        Jade.UI.MessageDialog.open({
            dialogButtons: Jade.UI.MessageDialogButtonStyle.Ok,
            dialogStyle: Jade.UI.MessageDialogStyle.Warning,
            message: message,
            select: function(e) {
                e.close();
            }
        });

    }

});

//================================
// SHARED METHODS
//================================

/**
@method open
@static
@return {Web.UI.FeatureSets.TargetEditorDialog}
**/
ProspectDirector.Web.UI.FeatureSets.TargetEditorDialog.open = function (options) {
    return new ProspectDirector.Web.UI.FeatureSets.TargetEditorDialog(options);
};
