/*
 * admin.js
 *
 * Author: Ricardo Dani
 * E-mail: ricardodani@gmail.com
 * */

// django jquery namespace
function option(val, verbose, type, selected) {
    /*
     * Return a $(<option>) with value, verbose and selected bool.
     * */
    var selected = selected || false;
    var $opt = $('<option>');
    $opt.val(val);
    $opt.text(verbose);
    if (selected == true) {
        $opt.attr('selected', 'selected');
    }
    if (type != null) {
        $opt.attr('data-type', type)
    }
    return $opt;
}

function populate_clean($inline_item) {
    var model_field = $inline_item.find('.introspect-model_field');
    $(model_field).empty(); 
    model_field.append(option('', '-------', null));
}

function populate_model_data($inline_item) {
    /*
     * populate_model_data($inline_item)
     * with a given $inline_item (jQuery object of a inline item)
     * populate the <select> `model_field` with the metadata located in
     * windows.queryset_reporter.model_data
     * accepts only 2 levels of recursion.
     * TODO: make this n-recursive
     * */
    var model_field = $inline_item.find('.introspect-model_field');
    var data = window.queryset_reporter.model_data;
    if (data.success) {
        $.each(data.fields, function (i, field) {
            model_field.append(option(field.name, field.verbose, field.type));
            handle_lookup_fields(model_field, field, field.name, field.verbose);
        });
    }
}

function handle_lookup_fields(model_field, field, field_name_prefix, field_verbose_prefix) {

    var lookup_fields = field.lookup_fields;
    if (typeof lookup_fields != 'undefined') {
        $.each(lookup_fields, function (l, lfield) {
            var lf_name = field_name_prefix + '__'  + lfield.name;
            var lf_verbose = field_verbose_prefix + ' -> ' + lfield.verbose;
            model_field.append(option(lf_name, lf_verbose, lfield.type));
            handle_lookup_fields(model_field, lfield, lf_name, lf_verbose);
        });
    }
}

function populate_model_defaults($inline_item) {

    // hidden with field name
    var field = $inline_item.find('.introspect-field');
    // hidden with verbose
    var verbose = $inline_item.find('.introspect-field_verbose');
    // select
    var model_field = $inline_item.find('.introspect-model_field');

    // if the hidden field `field` has data
    if (field.val().length > 0) {
        if (verbose.val().length == 0) {
            verbose = field;
        }
        var $opt = model_field.children('option[value=' + field.val() + ']');
        if ($opt.length > 0) {
            $opt.attr('selected', 'selected');
        }
    }
}

function model_field_populate_by_inline(index, value) {
    /*
     * model_field_default_by_inline()
     * for each form in the inline formset, makes the default values
     * for the model_field <select>, selecting what are equal to the hidden
     * `field`.
     */
    var selector = '.dynamic-' + value + '_set';
    var inline_itens = $(selector);

    // iterate through each form
    inline_itens.each(function(index, inline_item) {
        populate_clean($(inline_item));
        populate_model_data($(inline_item));
        populate_model_defaults($(inline_item));
    });
}

function model_field_populate() {
    /*
     * model_field_populate()
     * with an array of inline`s names, for each of them, execute the 
     * function `model_field_defaults_by_inline`, responsable for 
     * */
    var inlines = $(['displayfield', 'queryfilter']);
    inlines.each(model_field_populate_by_inline);
}

$(document).ready(function() {
   
    /*
     * for every change in the Model <select> execute the funcion to
     * retrieve a JSON via ajax to get the field metadata of the selected
     * model.
     * */
    $('#queryset_form #id_model').change(function(event) {
        var model = $(this);
        if (model.val().length > 0) {
            var url = window.QR_API_MODELFIELDS_URL;
            $.getJSON(url, {model: model.val()}, function(data) {
                // first, sets the model_data in a global object
                window.queryset_reporter = {model_data: data}
                // then call a method to populate 
                model_field_populate();
            });
        }
    }).change();

    /*
     * For every change in the `model_field` of the inlines.
     * Copies the <select> information to `field`, `field_verbose` and `field_type`.
     * */
    $('#queryset_form .introspect-model_field').live('change', function(event) {
        var $model_field = $(this);
        var $option = $model_field.find('option:selected');
        var $div_parent = $model_field.parent().parent();
        var $name = $div_parent.find('.introspect-field');
        var $verb = $div_parent.find('.introspect-field_verbose');
        var $type = $div_parent.find('.introspect-field_type');
        $verb.val($option.text());
        $name.val($option.val());
        $type.val($option.attr('data-type'));
    });

    /*
     * Whean adding a inline, intercept's the click and sync values with model field loaded data
     * */
    $('#queryset_form .add-row a').live('click', function(event) {
        model_field_populate();
    });
});
