/*
 * Funzioni di utilità per gestire le form django in maniera asincrona.
 *
 * Le form, intese come oggetti DOM renderizzate a partire da una form
 * django, vengono rese asincrone attraverso il plugin ajaxForm.
 *
 */

function removeErrorsFromForm(form) {
    /*
     * form è il jQuery collegato ad una o più form
     * elimina le classi e i nodi DOM che contengono i dettagli degli
     * errori
     */
    $('div.form-field', form).removeClass('field-error');
    $('div.form-field ul', form).remove();
};

function setErrorsToForm(form, errors) {
    /*
     * form è il jQuery collegato ad una o più form
     * errors è la risposta ottenuta inviando la form in maniera
     * asincrona
     *
     * aggiunge alla form le indicazioni sugli errori passati
     */
    removeErrorsFromForm(form);
    for(var ix=0; ix<errors.length; ix++) {
        var e = errors[ix];
        if(e['errors'].length) {
            var f = $('#' + e['field']).parent();
            f.addClass('field-error');
            var ul = $('<ul></ul>').appendTo(f);
            $.each(e['errors'], function() { $('<li>' + this + '</li>').appendTo(ul) });
        }
    }
};

function fillForm(data, prefix) {
    /*
     * riempie i campi della form passata con i valori presenti in data
     */
    prefix = prefix ? prefix + '-' : '';
    for(var key in data) {
        var id = '#id_' + prefix + key;
        var e = $(id);
        if(!e.length)
            continue;
        e.val(data[key]);
    }
};

function extractForm(form, prefix) {
    /*
     * estrae da una form i dati
     */
    prefix = prefix ? prefix + '-' : '';
    var form = $(form);
    var data = {};
    var l = prefix.length + 3;
    var f = function() {
        var key = this.id.substr(l);
        data[key] = $(this).val();
        if(this.nodeName.toLowerCase() == 'select') {
            var v = data[key];
            key += '_display';
            data[key] = $('option[value=' + v + ']', this).text();
        }
    };
    $('input', form).each(f);
    $('textarea', form).each(f);
    $('select', form).each(f);
    return data;
}

/* ****************************** */
function bind(f, scope) {
    function wrapper() {
        return f.apply(scope, arguments);
    }
    return wrapper;
};

function partial() {
    if(arguments.length==0)
        throw "partials need at least one argument";
    var args = $.makeArray(arguments);
    var f = args.shift();
    function wrapper() {
        return f.apply(this, args);
    }
    return wrapper;
};

function template() {
    var args = $.makeArray(arguments);
    var str = args.shift();
    for(var k in args) {
        str = str.replace('{' + k + '}', args[k], 'g');
    }
    return str
};

function autoTabs(sel) {
    var tab = $(sel).tabs();
    tab.bind('tabsselect', function(event, ui) {
        var fragment = '#t-' + ui.tab.href.split('#')[1];
        var r = /#[^?]*/;
        var url = document.location.href.replace(r, fragment);
        if(url == document.location.href && url.indexOf('#') == -1) {
            var q = url.indexOf('?');
            if(q == -1)
                url += fragment;
            else
                url = url.substr(0, q) + fragment + url.substr(q);
                
        }
        document.location.href = url;
    });
    var fragment = document.location.href.split('#')[1];
    if(fragment && fragment.substr(0,2) == 't-') {
        var ids = $.map($(sel + ' ul:first a'), function(e) { return e.href.split('#')[1]; });
        var ix = $.inArray(fragment.substr(2), ids);
        if(ix != -1)
            tab.tabs('select', ix);
    }
};


// Simple JavaScript Templating
// John Resig - http://ejohn.org/ - MIT Licensed
(function(){
  var cache = {};

  this.tmpl = function tmpl(str, data){
    // Figure out if we're getting a template, or if we need to
    // load the template - and be sure to cache the result.
    var fn = !/\W/.test(str) ?
      cache[str] = cache[str] ||
        tmpl(document.getElementById(str).innerHTML) :

      // Generate a reusable function that will serve as a template
      // generator (and which will be cached).
      new Function("obj",
        "var p=[],print=function(){p.push.apply(p,arguments);};" +

        // Introduce the data as local variables using with(){}
        "with(obj){p.push('" +

        // Convert the template into pure JavaScript
        str
          .replace(/[\r\t\n]/g, " ")
          .split("<%").join("\t")
          .replace(/((^|%>)[^\t]*)'/g, "$1\r")
          .replace(/\t=(.*?)%>/g, "',$1,'")
          .split("\t").join("');")
          .split("%>").join("p.push('")
          .split("\r").join("\\'")
      + "');}return p.join('');");

    // Provide some basic currying to the user
    return data ? fn( data ) : fn;
  };
})();


