﻿$(function () {
    $('._source').each(function () {
        var source = $(this);

        data[source.attr('id')] = $.parseJSON(source.html());
        source.remove();
    });

    $('[data-item][data-src]:input').live('change', function () {
        if (!utils.isLoading) {
            var item = $(this);
            var src = item.attr('data-src');
            
            if (src) {
                var value = item.val();

                utils.setValue(src, value);
            }
        }
    });

    utils.bindAllTemplates();
    utils.loadAllSelectLists();
    utils.bindAllData();
});

var dmiData = window.dmiData = {};
var data = dmiData.data = {};
var dataNamespace = 'dmiData.data';
var templates = dmiData.templates = {};
var utils = dmiData.utils = {};

utils.isLoading = false;

utils.guid = function () {
    function S4() {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    }

    return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
};

utils.setValue = function (src, value) {
    var last = src.lastIndexOf('.');
    var dataPath = src.substring(0, last);
    var property = src.substring(last + 1);
    var obj = eval(dataPath);
    obj[property] = value;

    $('[data-src=' + src + ']').each(function () {
        var item = $(this);

        item.filter(':input').attr('value', value);
        item.filter(':not(:input)').html(value);
    });
};

utils.bindAllTemplates = function () {
    $('[data-source]:not([data-source] [data-source]):not([data-source][data-item])').each(function () {
        var template = $(this);

        if(!template.attr('data-tmpl')) {
            var source = template.attr('data-source');
            var src = dataNamespace + '.' + source;
            var guid = utils.guid();

            templates[guid] = template.html();

            template.attr('data-src', src)
                        .attr('data-tmpl', guid)
        }
        
        template.html('');
        utils.bindTemplate(template);
    });
};

utils.bindAllData = function () {
    $('[data-item][data-src]').each(function () {
        var item = $(this);
        var value = eval(item.attr('data-src'));

        item.filter(':input').val(value);
        item.filter(':not(:input)').html(value);
    });
};

utils.bindTemplate = function (obj) {
    var tmpl = templates[obj.attr('data-tmpl')];
    var tag = obj.attr('tagName');
    var objSrc = obj.attr('data-src');

    tmpl = $('<' + tag + '>').html(tmpl);

    tmpl.find('[data-item]:not([data-source] [data-item])').each(function () {
        var item = $(this);
        var idx = obj.attr('data-idx');
        var property = item.attr('data-item');
        var src = idx
                ? objSrc + '[' + idx + ']' + '.' + property
                : objSrc + '.' + property;

        item.attr('data-src', src);
    });

    tmpl.find('[data-source]:not([data-source] [data-source]):not([data-item][data-source])').each(function () {
        var item = $(this);
        var source = item.attr('data-source');
        var idx = obj.attr('data-idx');
        var src = idx
                ? objSrc + '[' + idx + ']' + '.' + source
                : objSrc + '.' + source;
        var guid = utils.guid();
        var items = eval(src);

        templates[guid] = item.html();

        item.attr('data-src', src)
                .attr('data-tmpl', guid)
                .html('');

        $.each(items, function (index) {
            item.attr('data-idx', index)
            utils.bindTemplate(item);
        });
    });

    obj.append(tmpl.html());
}

utils.loadAllSelectLists = function () {
    var tmp = [];

    $('select[data-list]').each(function (index) {
        var list = $(this).attr('data-list');

        if (tmp.indexOf(list)) {
            tmp.push(list);

            utils.loadSelectList(list);
        }
    });
}

utils.loadSelectList = function (list) {
    var selects = $('select[data-list=' + list + ']');

    if (selects.length > 0) {
        var optionList = '<option value=""></option>';
        var data = eval(dataNamespace + '.' + list);

        $.each(data, function (item, value) {
            optionList += '<option value="' + value.Value + '">' + value.Text + '</option>';
        });

        selects.html(optionList);
    };
}

dmiData.save = function (options) {
    var settings = {
        url: '',
        submitButton: {
            disabled: true,
            processingValue: 'Saving...'
        }
    };

    $.extend(settings, options);

    var m = dataNamespace +  '.' + settings.model;
    var last = m.lastIndexOf('.');
    var dataPath = m.substring(0, last);
    var property = m.substring(last + 1);
    var obj = eval(dataPath);

    settings.data = { model: JSON.stringify(obj[property]) }

    settings.success = function (model) {
        obj[property] = model;
        utils.bindAllTemplates();
        utils.loadAllSelectLists();
        utils.bindAllData();

        if (options.success) { options.success(model); }
    };

    settings.error = function (request, error) {
        enableFormSubmits();

        if (options.error) {
            options.error(request, error);
        } else {
            $.jGrowl('ERROR: ' + error);
        }
    };

    utils.postJson(settings);
}

dmiData.execute = function (options) {
    var settings = {
        url: '',
        data: {},
        error: function (request, error) { $.jGrowl('ERROR: ' + error); }
    }

    $.extend(settings, options);

    utils.postJson(settings);
}

utils.postJson = function (settings) {
    $.ajax({
        type: 'POST',
        url: settings.url,
        data: settings.data,
        contentType: 'application/x-www-form-urlencoded',
        success: function (msg) {
            settings.success(msg);
        },
        error: function (request, error) {
            settings.error(request, error);
        },
        dataType: 'json'
    });
}

window.dmi = new function () {
    this.doIt = function (s) {
        alert(s);
    }
}
