﻿/// 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" />

// A subset of the server side repository
function NavitopiaRepository() {
    this.errorCallback = $(this).createCallback(this.getDataError);
    this.successCallback = $(this).createCallback(this.getDataSuccess);
    this.objectTypes = {
        Account: { key: "ProviderUserKey", data: [], displayName: "UserName" },
        MyGroups: { key: "UserGroupId", data: [], displayName: "Description" },
        Event: { key: "EventId", data: [], displayName: "Description" },
        Filter: { key: "FilterId", data: [], displayName: "Description" },
        Group: { key: "GroupId", data: [], displayName: "GroupName" },
        Location: { key: "LocationId", data: [], displayName: "LocationName" },
        Resource: { key: "ResourceId", data: [], displayName: "ResourceName" },
        ResourceShare: { key: "ShareId", data: [] },
        Rights: { key: "ResourceId", data: [] },
        Subscriber: { key: "SubscriberId", data: [], displayName: "SubscriberName" },
        Trip: { key: "WatchId", data: [] },
        AdvertisementInfo: { key: "Id", data: [], displayName: "Description" },
        Watch: { key: "WatchId", data: [] }
    };
}

NavitopiaRepository.prototype = {
    errorMessage: "",

    clearItems: function(typeName) {
        this.objectTypes[typeName].data = [];
    },

    createItem: function(typeName, id, data, callback) {
        this.doCreateUpdate(typeName, id, data, callback, "create");
    },

    deleteItem: function(typeName, keyValue, callback) {
        this.getData(typeName + "/delete/" + keyValue,
			{ typeName: typeName, callback: callback });
    },

    doCreateUpdate: function(typeName, id, data, callback, action) {
        this.getData(typeName + "/" + action + "/" + id,
			{ data: data, typeName: typeName, callback: callback });
    },

    findItem: function(typeName, keyValue) {
        var item;
        var items = this.objectTypes[typeName].data;
        var key = this.objectTypes[typeName].key;

        for (var index in items) {
            if (items[index][key] == keyValue) {
                item = items[index];
                item.index = index;
                break;
            }
        }

        return item;
    },

    getActionUrl: function(url) {
        url = "/" + url;
        return url;
//        if (this.subscriber.isDefault) return url;
//        else return "/" + this.subscriber.name + url;
    },

    getData: function(url, callerOptions) {
        var options = {};

        this.callerOptions = callerOptions;

        if (callerOptions.async === false) options.async = false;
        if (callerOptions.timeout) options.timeout = callerOptions.timeout;
        if (callerOptions.type) options.type = callerOptions.type;

        if (callerOptions.cache) options.cache = callerOptions.cache;
        else options.cache = false;

        options.data = callerOptions.data;
        options.dataType = "json";
        options.url = this.getActionUrl(url);

        options.error = this.errorCallback;
        options.success = this.successCallback;

        $.ajax(options);
    },

    getDataError: function(request, status) {
        var message = request.responseText;

        if (!message || "" == message) message = status;

        this.errorMessage = message;
        this.status = status;

        if ($.isFunction(this.callerOptions.callback))
            this.callerOptions.callback();
    },

    getDataSuccess: function(data, status) {
        var item, value;
        var typeName = this.callerOptions.typeName;
        var type = this.objectTypes[typeName];

        if (!data || 0 == data.length) {
            type.data = [];
        } else if ($.isArray(data) && data[0][type.key]) {
            type.data = data;
        } else if (!$.isArray(data) && data[type.key]) {
            item = this.findItem(typeName, data[type.key]);

            if (item) type.data[item.index] = data;
            else type.data.push(data);
        } else if (!$.isArray(data) && "undefined" != typeof (data["value"])) {
            value = data.value;
        } else if (!$.isArray(data) && data["deleted"]) {
            this.removeItem(typeName, data.deleted);
        } else {
            if (200 == data.status) value = data.responseText;
            else {
                if (data.responseText) this.errorMessage = data.responseText;
                else this.errorMessage = data;
                status = "error";
            }
        }

        this.objectTypes[typeName] = type;
        this.status = status;

        if ($.isFunction(this.callerOptions.callback))
            this.callerOptions.callback(value);
    },

    getItem: function(typeName, keyValue, callback) {
        if ($.isFunction(keyValue)) {
            callback = keyValue;
            keyValue = "";
        }

        if (!$.isFunction(callback)) return this.findItem(typeName, keyValue);
        else {
            this.getData(typeName + "/GetData/" + keyValue,
				{ typeName: typeName, callback: callback });
        }
    },

    getList: function(typeName, keyValue, callback) {
        if ($.isFunction(keyValue)) {
            callback = keyValue;
            keyValue = "";
        }

        if (!$.isFunction(callback)) return this.objectTypes[typeName].data;
        else {
            var urlParts = typeName.split("/");
            var url;

            if (1 == urlParts.length) urlParts.push("GetData");
            url = urlParts.join("/") + "/";

            this.getData(url + keyValue,
				{ typeName: urlParts[0], callback: callback });
        }
    },

    haveItems: function(typeName) {
        return (0 != this.objectTypes[typeName].data.length);
    },

    removeItem: function(typeName, keyValue) {
        var item = this.findItem(typeName, keyValue);

        if (item) {
            this.objectTypes[typeName].data.splice(item.index, 1);
        }
    },

    status: "",

    subscriber: {},

    updateItem: function(typeName, id, data, callback) {
        this.doCreateUpdate(typeName, id, data, callback, "update");
    }
}

// Default repository
var _repository = new NavitopiaRepository();
