﻿/// For Intellisense
/// <reference path="jquery-1.3.2-vsdoc.js" />
/// <reference path="jquery-ui-1.7.2.custom.js" />
/// <reference path="MicrosoftAjax.debug.js" />
/// <reference path="MicrosoftAjaxTemplates.debug.js" />
/// <reference path="MicrosoftMvcAjax.debug.js" />
/// <reference path="Navitopia.jQuery.js" />
/// <reference path="NavitopiaRepository.js" />
/// <reference path="NavitopiaCrud.js" />
/// <reference path="Navitopia.js" />

// Handles create/edit (assigned in each view's index.aspx)
var _crudManager;

// Default repository (assigned in NavitopiaRepository.js)
var _repository;

// CRUD helpers
function CrudManager(typeName, dialogOptions) {
    this.typeName = typeName;
    this.contentSelector =  "#ajax-content-container";
    this.dialogSelector =  "#ajax-dialog-container";

    this.createTemplate =  "createTemplate";
    this.editTemplate =  "editTemplate";
    this.listTemplate =  "listTemplate";
    this.rightsTemplate =  "rightsTemplate";
    this.templateModifier =  null;

    this.repository =  _repository;

    // If dialogOptions are passed in we want to assign 
    // them to 'this' without overwriting the prototype
    if (dialogOptions) {
        this.dialogOptions = {};

        // First get defaults
        for (key in CrudManager.prototype.dialogOptions)
            this.dialogOptions[key] = CrudManager.prototype.dialogOptions[key];

        // Now overwrite them with passed in differences
        for (key in dialogOptions)
            this.dialogOptions[key] = dialogOptions[key];
    }

    if (!this.dialogOptions.hasOwnProperty("close")) {
        var callback = function() { if (!_errorOccurred) this.cancelEdit(); }
        this.dialogOptions.close = $(this).createCallback(callback);
    }

    this.isCreateState = this.isEditState = false;
}

CrudManager.prototype = {
    listTemplate: "listTemplate",

    dialogOptions: {
        dialogClass: "dialog-crud",
        bgiframe: true,
        modal: true,
        width: "600px"
    },

    cancelEdit: function() {
        clearErrors();
        this.destroyDialog();
    },

    clearContent: function() {
        $(this.contentSelector).empty();
    },

    createItem: function(callback) {
        if ($("#createForm").validateForm())
            this.doCreateUpdate(callback, "create");
    },

    deleteItem: function(keyValue, callback) {
        if (ask("This will permanently delete this " + this.typeName + ". Do you wish to continue?")) {
            if (!callback && callback !== false) callback = this.showListView;
            this.repository.deleteItem(this.typeName, keyValue, $(this).createCallback(callback));
        }
    },

    destroyDialog: function() { $(this.dialogSelector).dialog("destroy"); },

    doCreateUpdate: function(callback, action) {
        var item;

        if ("function" == typeof (getFormData)) item = getFormData();
        else item = $("form").getFormValues();

        if (item) {
            clearErrors();
            if (!callback && callback !== false) callback = this.showListView;
            this.repository.doCreateUpdate(this.typeName, idField().val(),
				item, $(this).createCallback(callback), action);
        }
    },

    doEditView: function(keyValue, postShowCallback) {
        if (this.haveErrors()) this.showError();
        else {
            var item = this.repository.findItem(this.typeName, keyValue);

            if (item) {
                this.showTemplateDialog(this.editTemplate, item);
                if ($.isFunction(postShowCallback)) postShowCallback(keyValue);
            }
        }
    },

    doRightsView: function(keyValue, postShowCallback) {
        if (this.haveErrors()) this.showError();
        else {
            var item = this.repository.findItem("Rights", keyValue);

            if (item) {
                this.showTemplateDialog(this.rightsTemplate, item);
                $("#tabs").tabs();

                var resource = this.repository.findItem("Resource", keyValue);

                if (resource && resource.IsShared) $("#tabs").tabs("disable", 1);

                for (var index in item.Groups) {
                    var group = item.Groups[index];
                    var groupId = group.GroupId
                    var callback = function() { _crudManager.setRights(this); };
                    var selection = $("#" + groupId)
						.add("#" + groupId + " + tr")
						.setRights(group.AllowRights, group.DenyRights);

                    $("input:checkbox", selection)
						.add("#" + groupId + " + tr input:checkbox")
						.click(callback).data("keyValue", keyValue).data("groupId", groupId);
                }

                $("#permissions tbody tr:even").addClass("odd");

                if ("Event" == this.typeName)
                    $("input[value=" + rightsCRUD + "]").attr("disabled", true);

                if (this.repository.haveItems("ResourceShare")) {
                    var shares = this.repository.getList("ResourceShare");
                    var callback = function() { _crudManager.setShareRights(this); };

                    for (var index in shares) {
                        var share = shares[index];
                        var shareId = share.ShareId.toUpperCase();
                        var selection = $("#" + shareId).setRights(0, share.DenyRights);

                        $(".ResourcePermission", selection)
							.attr("checked", share.ResourcePermissions == resourcePermissionEdit);
                        $("input:checkbox", selection)
							.click(callback)
							.data("keyValue", keyValue).data("shareId", shareId).data("status", share.Status)
							.data("targetSubscriberName", share.TargetSubscriberName);
                    }
                }

                $("#CreateShare").data("keyValue", keyValue);

                if ($.isFunction(postShowCallback)) postShowCallback(keyValue);
            }
        }
    },

    haveErrors: function() {
        return this.repository.status && "success" != this.repository.status;
    },

    setRights: function(elm) {
        var keyValue = $(elm).data("keyValue");
        var groupId = $(elm).data("groupId");
        var options = { callback: false, typeName: "Rights" };
        var data = $("#" + groupId).add("#" + groupId + " + tr").getRights();

        data.groupId = groupId;
        options.data = data;

        this.repository.getData(this.typeName + "/Rights/" + keyValue, options);
    },

    setShareRights: function(elm, status) {
        var options = { typeName: "ResourceShare" };
        var data, keyValue;

        if (elm) {
            var shareId = $(elm).data("shareId");

            options.callback = false;
            keyValue = $(elm).data("keyValue");

            data = $("#" + shareId).getRights();
            data.shareId = shareId;

            if (status) {
                data.newStatus = status;
                if (status == shareStatusWithdrawn) options.callback =
					$(this).createCallback(function() { this.showRightsView(keyValue, true); });
            }

            data.targetSubscriberName = $(elm).data("targetSubscriberName");
            data.resourcePermissions =
				$("#" + shareId + " .ResourcePermission")
				.attr("checked") ? resourcePermissionEdit : resourcePermissionNone;
        } else {
            options.callback = $(this).createCallback(this.showListView);
            keyValue = $("#CreateShare").data("keyValue");

            data = $("#CreateShare").getRights();
            data.targetSubscriberName = $("#TargetSubscriberName").val();
            data.resourcePermissions =
				$("#CreateShare .ResourcePermission")
				.attr("checked") ? resourcePermissionEdit : resourcePermissionNone;
        }

        options.data = data;

        this.repository.getData("Resource/Shares/" + keyValue, options);
    },

    showCreateView: function(templateModifier, postShowCallback) {
        if ($.isFunction(templateModifier)) {
            postShowCallback = templateModifier;
            templateModifier = null;
        }

        this.templateModifier = templateModifier;
        this.isCreateState = true; this.isEditState = false;

        this.showTemplateDialog(this.createTemplate);
        if ($.isFunction(postShowCallback)) postShowCallback();
    },

    showDialog: function(dialogSelector, dialogOptions) {
        if (!dialogOptions) dialogOptions = this.dialogOptions;

        $(dialogSelector)
			.prepend($("<div id='dlg-messages'>"))
			.dialog(dialogOptions)
			.show();

        $("tbody tr:even", dialogSelector).addClass("odd");
        $(".datepicker", dialogSelector).datepicker();
        $("input[type='text']", dialogSelector).format()
			.change(function() { $(this).format(); });

        $("input", dialogSelector).not(":hidden").not(":button").eq(0).select();
    },

    showEdit: function(keyValue, templateModifier) {
        if (this.repository.haveItems(this.typeName)) {
            this.showEditView(keyValue, templateModifier)
        }
        else {
            this.repository.getItem(this.typeName, keyValue, $(this).createCallback(this.showEditView));
        }
    },

    showEditView: function(keyValue, templateModifier, postShowCallback) {
        if ($.isFunction(templateModifier)) {
            postShowCallback = templateModifier;
            templateModifier = null;
        }

        this.templateModifier = templateModifier;
        this.isCreateState = false; this.isEditState = true;

        this.repository.getItem(this.typeName, keyValue,
			$(this).createCallback(function() { this.doEditView(keyValue, postShowCallback); }));
    },

    showError: function() {
        showError(this.repository.errorMessage);
    },

    showList: function(keyValue) {
        if (!keyValue) {
            if (window.location.href.indexOf("Details") > 0) {
                if (isCreate)
                    window.location = '/Trip/Details/' + this.repository.objectTypes.Trip.data[0].WatchId;
                else window.location = '/Home/Index/';
            }
            else {
                if (this.repository.haveItems(this.typeName)) this.showListView();
                else {
                    this.repository.getList(this.typeName, $(this).createCallback(this.showListView));
                }
            }
        } else {
            this.repository.getList(this.typeName, keyValue, $(this).createCallback(this.showListView));
        }

    },

    showListView: function() {
        if (this.haveErrors()) this.showError();
        else {
            $(this.destroyDialog());
            $(this.contentSelector)
				.fillTemplate(this.listTemplate,
					this.repository.objectTypes[this.typeName].data);
            //$("tbody tr:even", this.contentSelector).addClass("odd");
            $("*", this.contentSelector).format();
            AddTableWidgets();

        }
    },

    showRightsView: function(keyValue, showShares, postShowCallback) {
        if ($.isFunction(showShares)) {
            postShowCallback = showShares;
            showShares = null;
        }

        this.templateModifier = null;

        var options;

        if (!this.repository.haveItems("Group")) {
            options = { callback: false, async: false, timeout: 5000, typeName: "Group" };
            this.repository.getData("Group/GetData/", options);
        }

        if (showShares && !this.repository.haveItems("ResourceShare")) {
            options = { callback: false, async: false, timeout: 5000, typeName: "ResourceShare" };
            this.repository.getData("Resource/Shares/", options);
        }

        options = { callback: $(this).createCallback(function() {
            this.doRightsView(keyValue, postShowCallback);
        }), typeName: "Rights"
        };

        this.repository.getData(this.typeName + "/Rights/" + keyValue, options);
    },

    showTemplateDialog: function(templateId, data) {
        if (this.templateModifier)
            templateId += this.templateModifier;

        $(this.dialogSelector).fillTemplate(templateId, data);
        this.showDialog(this.dialogSelector);
    },

    updateItem: function(callback) {
        if ($("#editForm").validateForm())
            this.doCreateUpdate(callback, "update");
    }
};
