/*******************************************************************************
 * @name: muchtour.js
 * @purpose: contém as funções que são utilizadas em todos os contextos do
 *           muchtour.
 *
 *
 * @author: Ruhan Bidart - ruhan@2xt.com.br
 * @since: 24/03/2009
 ******************************************************************************/

 
var __datepicker_defaults = {
    dayNamesShort: ['D', 'S', 'T', 'Q', 'Q', 'S', 'S'],

    dayNames: ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta',
               'Sábado'],

    monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', 'Julho',
                'Agosto','Setembro','Outubro','Novembro','Dezembro'],

    monthNamesShort: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', 'Julho',
                      'Agosto','Setembro','Outubro','Novembro','Dezembro'],
    dateFormat: 'dd/mm/yy',
    altFormat: 'dd/mm/yy',
    nextText: 'Próximo Mês',
    prevText: 'Mês Anterior',
    changeYear: true,
    changeMonth: true,
    constrainInput: true
};

// O nome do cookie que controlará qual o último módulo aberto
var _cookie_ultimo_modulo_aberto = 'muchtour.ultimo_modulo_aberto';

// Data de expiração dos cookies das abas (tempo extenso, 10 anos =D)
var date = new Date();
date.setTime(date.getTime() + (3 * 24 * 60 * 60 * 1000 * 10));
var _cookie_ultimo_modulo_aberto_expires = date;


function scroll_to_element(element, frame) {
    // Called by clicking on a link in the left-side table of contents in the main page.
    // The argument 'element' is the element identifier of a paragraph in the agreement draft,
    // which is located is is in an iframe (‘ContentFrame’) on the right of the main page.

    // FIX2XT: Utilizando a variável frame para indicar se irá pegar o element do frame ou da página principal
    if (frame)
        var obj_temp = top.frames[frame].document.getElementById(element);
    else
        var obj_temp = document.getElementById(element);
    var style_anterior = obj_temp.style.display;
    obj_temp.style.display = 'block';
    var tmp = get_pos(obj_temp);
    // getPos is a routine that determines where in the document
    // the 'element' paragraph is located
    // FIX2XT: Removida a próxima linha, pois como utilizamos no frame o padrão de resize deste
    // deveremos utilizar o scroll da página principal, e não do próprio frame. Portanto utiliza-se
    // o scrollTo apenas no top
    //top.frames["iframe_muchtour"].scrollTo(0, tmp);
    top.scrollTo(0, tmp);
    // I had to prepend the ‘top.frames["ContentFrame"].’ part
    // to make it work in Safari and Google Chrome.
    // The original code is more succinct; I expanded it
    // for debugging purposes.
    // FIX2XT: Retornando o style anterior do elemento
    obj_temp.style.display = style_anterior;
};


function get_pos(e) {
    var y = 0;

    do {
        var yd = e['offsetTop'];
        y += isNaN(yd) ? 0 : yd;
        e = e.offsetParent;
    } while (e && e!=document.body);

    return y;
}

/* Funções de aguarde */
/**
 * ATENÇÃO: Se você está lendo este comentário, provaavelmente  vc está tendo dificuldadades
 * com o Thickbox. Caso o erro que vc enfrente é um que quando vc chama a função mostrar_aguarde()
 * aparece apenas um fundo preto na tela  e o aguarde não aparece, vc deve se certificar de que
 * o JavaScript thickbox.min.js foi incluído na página ANTES  da página que implementa a logica que
 * que utiliza o javascript
 */
function mostrar_aguarde() {
    //jQuery("TB_load").remove();
    jQuery("#TB_overlay").remove();
    jQuery("#TB_window").remove();
    var union = window.location.href.search('\\?') == -1 ? '?' : '&';
    var a = jQuery('<a href="#TB_inline' + union + 'height=220&width=330&inlineId=aguarde&modal=true&random=' + Math.random() + '" id="link_aguarde" class="thickbox">&nbsp;</a>').appendTo('body');
    thickbox_atualizar_elemento(a);
    a.click();
}

function esconder_aguarde() {
    tb_remove();
}

function mostrar_aguarde_thickbox() {
    if (!Boolean(jQuery('.aguarde_thickbox').length)) {
        var div = jQuery('<div>' +
                         '<center>' + 
						 '<img src=' + _url_estatica + 'img/aguarde.gif />' + 
                         '</center>' + 
                     '</div>').attr('id', 'TB_load').addClass('aguarde_thickbox');
        div.appendTo("body");
    }
    jQuery('#TB_load').show();
}

function esconder_aguarde_thickbox() {
    jQuery('#TB_load').hide();
}

/*
* Função que pega um objeto form, que possui objetos de formulário
* "input", "select" e "textarea" através do filtro ":input" do jQuery
*  e os transforma em objeto JSON.
*/
function transform_toJSON(object) {
    var dict = {};
    var dict_principal = {}
    object.find(':input').each(function(){
        dict[jQuery(this).attr('id')] = jQuery(this).attr('value');
    });
    dict_principal[object.attr('id')] = dict
    json_object = $.toJSON(dict_principal);
    return json_object;
}

/*
* Atualiza os elementos que o tickbox pode cobrir, visto que elementos que
* abrem thickboxes podem ser inseridos dinamicamente.
*/
function thickbox_atualizar_elemento(elemento){
    tb_init(jQuery(elemento));
}

/*
* Função que remove um elemento thickbox, exibindo um aguarde logo após
* a janela se esconder por completo. É a mesma da biblioteca thickbox,
* com as modificações supracitadas.
*/
function tb_remove_fast() {
    jQuery("#TB_imageOff").unbind("click");
    jQuery("#TB_closeWindowButton").unbind("click");
    //jQuery("#TB_window").fadeOut("fast",function(){jQuery('#TB_window,#TB_overlay,#TB_HideSelect').trigger("unload").unbind().remove(); mostrar_aguarde()});
    jQuery("#TB_window").hide();
    jQuery('#TB_window,#TB_overlay,#TB_HideSelect').trigger("unload").unbind().remove();
    mostrar_aguarde();
    jQuery("#TB_load").remove();
    if (typeof document.body.style.maxHeight == "undefined") {//if IE 6
        jQuery("body","html").css({height: "auto", width: "auto"});
        jQuery("html").css("overflow","");
    }
    document.onkeydown = "";
    document.onkeyup = "";
    return false;
}


// Lista com os valores das porcentagens de margem esquerda
// permitida no topo da página.
var percents_progresso = [3, 26, 49, 72, 95];

/*
* Função que avança a barra de progresso para a localização desejada pelo
* Usuário.
*
* x assume o indice no vetor percents_progresso correspondente À página atual.
* status pode assumir: qualquer uma das classes descritas pelos spans que
* estão na barra de progresos.
*/
function atualiza_progresso(x, status){
    //jQuery(".linha_cima td:first-child").width(porcentagem_termino + "%");
    jQuery(".linha_cima td:first-child").width(percents_progresso[x] + "%");

    jQuery('.progresso_ativo').removeClass('progresso_ativo');
    jQuery('.linha_progresso .' + status).addClass('progresso_ativo');
}


/*
* Funcao que altera a visibilidade de elementos html,
*  visto que o método toogle() do JQuery não o faz para
*  todos os elementos testados por este autor.
*/
function toogle_visibility(item){
    var item = jQuery(item);
    item.each(function(){
        if (jQuery(this).attr('escondido') == 'Sim'){
            jQuery(this).show();
            jQuery(this).attr('escondido', 'Nao');
        } else {
            jQuery(this).hide();
            jQuery(this).attr('escondido', 'Sim');
        }
    });
}

function special_sort(array) {
    var sorted_array = array.sort(function(a,b) {
    if(a > b) { return 1 }
    else { return 0 }
    });
    return sorted_array
}
/*
* Funcão que converte  para o formato da moeda passada por pârametro
*/
function to_money(number, currency, pos){
    // Caso o número tenha mais que duas casas decimais, soma-se mais um centavo
    // à quantia total. Este é um padrão adotado no MuchTour. Dessa forma iguala-se
    // o funcionamento da tag do template do django chamada `to_money`
    if (number * 100 / Math.floor(number * 100) > 1) {
        number = Math.floor(number * 100) / 100 + 0.01;
    } 

    if (pos == 1) return currency + ' ' + new String(parseFloat(number).toFixed(2)).replace('.', ',');
    else if (pos == 2) return new String(parseFloat(number).toFixed(2)).replace('.', ',') + ' ' + currency;
}

/*
* Funcão que converte  para o formato double de javascript
*/
function to_double(money) {
    return Number(money.replace(/[^0-9\,]+/g,"").replace(',','.'));
}

/**
 * Calcula o periodo de dias entre duas datas
 */
function calcula_periodo(data_inicio, data_fim) {
    var l_data_inicio = data_inicio.split('/');
    var l_data_fim = data_fim.split('/');
    var d_inicio = new Date(l_data_inicio[2], parseInt(l_data_inicio[1], 10)-1, l_data_inicio[0]);
    var d_fim = new Date(l_data_fim[2], parseInt(l_data_fim[1], 10)-1, l_data_fim[0]);

    // Calculamos o intervalor em dias (vem em milissegundos)
    return Math.round((d_fim-d_inicio)/(24 * 60 * 60 * 1000));
}
/**
 * Cria uma função dentro do padrão do jquery criadora de popups
 */
$.popup = function(pageURL, title, w, h, options) {
    var left = (screen.width/2)-(w/2);
    var top = (screen.height/2)-(h/2);
    var params = 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no';
    if(options) {
        options = params + ',' + options;
    } else {
        options = params;
    }
    var targetWin = window.open(pageURL, title, (options + ', width=' + w + ', height=' + h + ', top=' + top + ', left=' + left));
    return targetWin;
};

/**
 * Extende o JQuery inserindo uma função de comparação (equals) em cada objeto
 */
$.fn.equals = function(compareTo) {
    if (!compareTo || !compareTo.length || this.length!=compareTo.length) {
        return false;
    }
    for (var i=0; i<this.length; i++) {
        if (this[i]!==compareTo[i]) {
            return false;
        }
    }
    return true;
};

function get_IE_version() {
    var rv = -1;
    if (navigator.appName == 'Microsoft Internet Explorer') {
        var ua = navigator.userAgent;
        var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
        if (re.exec(ua) != null)
            rv = parseFloat(RegExp.$1);
    }
    return rv;
}

function recupera_dados_form(form){
    var dados = {};
    jQuery(form).not('[nao_me_gere_automaticamente]').find(':input, textarea').each(function(){
        // Caso o grupo não esteja definido no input coloca-se o grupo como 'geral'
        var grupo = jQuery(this).attr('grupo');
        var grupo = grupo != undefined ? grupo : 'geral';

        // Cria a função append, onde caso o objeto possua o name terminado com "@records" é criado uma
        // lista para não sobrepor valores
        var obj_name = jQuery(this).attr('name') || "";
        if (obj_name.indexOf('@records') != '-1') {
            // Caso não exista list do grupo, este é criado
            if (dados[grupo] == undefined) dados[grupo] = [{}];
            var obj_substr = obj_name.substr(0, obj_name.length-8);

                var adicionado = false;
                while (adicionado == false) {
                    for (var i=0; i < dados[grupo].length; i++) {
                        if (dados[grupo][i][obj_substr] == undefined) {
                            var append_in = function(x) {
                                dados[grupo][i][obj_substr] = x;
                            };
                            adicionado = true;
                            break;
                        }
                        // Caso esteja no ultimo elemento e tiverem todos repetidos adiciona
                        // um novo dicionário
                        else if (i == dados[grupo].length-1) {
                            var append_in = function(x) {
                                var dic = {};
                                dic[obj_substr] = x;
                                dados[grupo].push(dic);
                            }
                            adicionado = true;
                            break;
                        }
                        else continue;
                    }
                }

        }
        else {
            // Caso não exista dict/list do grupo, este é criado
            if (dados[grupo] == undefined) dados[grupo] = {};
            var append_in = function(x) {
                if (dados[grupo][obj_name] == undefined)
                    dados[grupo][obj_name] = {};
                dados[grupo][obj_name] = x;
            };
        }

        if (this.type == 'radio' || this.type == 'checkbox') {
            if (this.checked) append_in(jQuery(this).val());
        }
        else {
            append_in(jQuery(this).val());
        }

        /*// Trava de segurança
        if (jQuery(this).parent().children('#'+ jQuery(this).attr('name') + '_span').length != 0)
        {
            if(jQuery(this).val() != jQuery(this).parent().children('#'+ jQuery(this).attr('name') + '_span').text())
            {
                alert('Operação não permitida. Dados enviados diferem com os dados pesquisados.\nRecarregue a página');
                return false;
            }
        }*/
    });
    return dados;
}


/*
* Setamos qual foi o último modulo visitado anteriormente em um cookie.
* Estas funções são chamadas na pagina inicial de cada modulo.
*/
function ajusta_ultimo_modulo_visitado(){
    // O proprio modulo de relatorios irá setar o valor do último modulo
    // descoberto como relatorio.
    $.cookie(_cookie_ultimo_modulo_aberto, _modulo, { path: '/',
                                expires: _cookie_ultimo_modulo_aberto_expires });
}

function restaura_ultimo_modulo_visitado() {
    return $.cookie(_cookie_ultimo_modulo_aberto);
}

function cancele_com_operador() {
    alert('Entre em contato com um operador para efetuar o cancelamento pois você \nnão possui permissão suficiente para efetuar este procedimento.');
}

// Recebe um uri e redireciona relativo a url da agencia em questao
// FIXME: Esta função está replicada em muchtour.admin.geral.js, se você
// modifica-la, faça-o também por lá.
function get_url_relativa(uri) {
    // Corrigindo imperfeicoes (mais de uma barra) que pode provir de alguns
    // frames
    var url = window.location.href.replace(/\/\//g, '/');
    return window.location.href.split(url.split('/')[3] + '/')[0] + uri;
}

function redirect_relativo(uri) {
    window.location.href = get_url_relativa(uri);
}

// Função utilizada para impressão do conteúdo do thickbox
// Para ela funcionar corretamente o thickbox deve ser aberto com o parâmetro
// TB_iframe=true colocado na URL, para que o thickbox seja aberto num
// iframe
function imprimir_thickbox() {
    var iframe = jQuery('#TB_iframeContent')[0];
    var e_document = iframe.contentDocument || iframe.contentWindow.document;
    var e_btn_imprimir = jQuery(e_document.getElementById('btn_imprimir_thickbox'));
    e_btn_imprimir.hide();
    iframe.contentWindow.focus();
    iframe.contentWindow.print();
    e_btn_imprimir.show();
}

/**
 * Realiza o dump de um objeto como um formulário, as chaves que forem objetos
 * são convertidas em {String} do tipo json
 *
 * @author <a href="mailto:proberto.macedo@gmail.com">Paulo Roberto</a>
 *
 * @param {Object} object
 * @returns {Array} lista com os inputs gerados.
 */
function dump_as_form(object) {
    var inputs = [];
    $.each(object, function (key, value) {
        if (typeof value == "object")
            value = $.toJSON(value)
        inputs.push(jQuery('<input type="hidden" />').attr({
            name: key,
            value: value
        }).get(0))
    });
    return inputs;
}

/**
 * Função simples para não causar erros caso o console do firebug não esteja
 * presente.
 *
 * @author <a href="mailto:proberto.macedo@gmail.com">Paulo Roberto</a>
 */
var _dbg = function () {}
if (window.top.console != null)
    if (window.top.console.log != null)
        _dbg = window.top.console.log;

/**
 * Função para realizar o dump ou cópia do objeto de forma fácil.
 *
 * @author <a href="mailto:proberto.macedo@gmail.com">Paulo Roberto</a>
 *
 * @param {Object} object
 * @param {Array} attrs Atributos para retornar no dump.
 * @params {Object} extra Informação extra a adicionar ao dump.
 * @returns {Array} Lista de input para montar o formulário.
 */
function object_dump(object, attrs, extra)
{
    var basedump = {};
    // Attrs normais para o dump
    $.each(attrs, function (index, attr) {
        basedump[attr] = self[attr];
    })
    // Attrs com nomes diferentes do {Object}
    $.extend(basedump, extra);
    return basedump;
}

/**
 * Função que garante um parseFloat !
 *
 * @author <a href="mailto:proberto.macedo@gmail.com">Paulo Roberto</a>
 *
 * @param {Object} object a ser transformado em float.
 * @returns {Float}
 */
function parseFloat2(object)
{
    if (typeof object == 'string')
    {
        object = object.split(" ")[0];
    }
    return parseFloat(object);
}

/**
 * Bake a bacon.
 *
 * @author <a href="mailto:proberto.macedo@gmail.com">Paulo Roberto</a>
 *
 * @param {float} value valor a ser transformado.
 * @returns {string}
 */
function float2money(value, moeda)
{
    if (moeda == undefined) moeda = "R$";

    return to_money(parseFloat(value), moeda, 1);
}

/**
 * Removes intersection between array1 and array2 on array1 and returns a new
 * array.
 *
 * @author <a href="mailto:proberto.macedo@gmail.com">Paulo Roberto</a>
 *
 * @param {array} array1 First array
 * @param {array} array2 Second array
 * @returns {array}
 */
function array_remove(array1, array2) {
    return $.grep(array1, function (item, index) {
        return ($.inArray(item, array2) == -1);
    });
}

/**
 * Returns the intersection between array1 and array2.
 *
 * @author <a href="mailto:proberto.macedo@gmail.com">Paulo Roberto</a>
 *
 * @param {array} array1 First array
 * @param {array} array2 Second array
 * @returns {array}
 */
function array_intersection(array1, array2) {
    return $.grep(array1, function (item, index) {
        return ($.inArray(item, array2) >= 0);
    });
}


/**
 * Inclui outro script JS dentro da página atual. Interessante o uso quando não
 * é possível alterar a página e é necessário inserir um
 */
function carrega_css_js(filename, filetype){
    if (filetype=="js"){
        jQuery("head").append(jQuery("<script>").attr({
            type: "text/javascript",
            src: filename
        }));
    }
    else if (filetype=="css"){
        jQuery("head").append(jQuery("<link>").attr({
            rel: "stylesheet",
            type: "text/css",
            href: filename
        }));
    }

}

/**
 * Transforma uma string HH:MM em Float
 *
 * @author <a href="mailto:proberto.macedo@gmail.com">Paulo Roberto</a>
 *
 * @param {string} hora Hora para ser transformada.
 * @returns {float} Valor em float da hora.
 */
function hora2float(hora) {
    var nil = hora.split(":")
    return parseFloat(nil[0]) + (1 / 60. * parseFloat(nil[1]))
}

function zeroFill(number, width)
{
  width -= number.toString().length;
  if ( width > 0 )
  {
    return new Array(width + (/\./.test( number ) ? 2 : 1)).join('0') + number;
  }
  return number;
}

/**
 * Transforma uma tempo float em minutos para string no formato desejado.
 *
 * @author <a href="mailto:proberto.macedo@gmail.com">Paulo Roberto</a>
 *
 * @param {float} tempo Valor em minutos.
 * @returns {string} string montada.
 */
function float2hora(tempo, params) {
    var params = $.extend({
        separator: "h",
        suffix: "m"
    }, params);
    var h = parseInt(tempo / 60);
    var m = parseInt(tempo % 60);
    return h + params.separator + zeroFill(m, 2) + params.suffix;
}

