function arrayPush() {
  for(var i = 0; i < arguments.length; i++) {
    this[this.length] = arguments[i];
  }
}

var initFuncs = new Array();
var finishFuncs = new Array();
if (initFuncs.push == null) {
  initFuncs.push = arrayPush;
  finishFuncs.push = arrayPush;
}

function call_or_eval(code) {
  if(typeof(code) == 'function') {
    return code();
  } else {
    return eval(code);
  }
}

function callInitFuncs() {
  for(var i = 0; i < initFuncs.length; i++) {
    try {
      call_or_eval(initFuncs[i]);
    } catch (e) {
    }
  }
}

function callFinishFuncs() {
  for(var i = finishFuncs.length - 1; i >= 0; i--) {
    try {
      call_or_eval(finishFuncs[i]);
    } catch (e) {
    }
  }
}

window.onunload = callFinishFuncs;

function move_cursor(name)
{
    var elts = document.getElementsByName(name);
    if(elts.length > 0) {
        elts[0].focus();
    }
}

function rtk_for_each(array_or_obj, fn)
{
    if(!array_or_obj.length)
        fn(array_or_obj);
    else
        for(var i = 0; i < array_or_obj.length; ++i)
            fn(array_or_obj[i]);
}

function rtk_chain(f, g)
{
    return function() {
        var r;
        if(f && f.apply) r = f.apply(this, arguments);
        if(g && g.apply) r = g.apply(this, arguments);
        return r;
    };
}

function rtk_event(ev)
{
    return ev ? ev : window.event;
}

function rtk_source_element(ev, tagName)
{
    var el = Event.element(rtk_event(ev));

    if(tagName)
        while(el && el.tagName.toLowerCase() != tagName.toLowerCase()) {
            el = el.parentNode;
        }

    return el;
}

function showHideToggle() {
    var obj, i;
    for (i=0;i<arguments.length;i++){
        obj = arguments[i].indexOf
            ? findObj(arguments[i])
            : arguments[i];
        if (obj){
            var hide = (obj.style.display == 'inline');
            obj.style.display = (hide? "none" : "inline");
        }
    }
}

function showHideLayers() {
  var i, p, v, obj;
  var args = showHideLayers.arguments;
  for (i = 0; i < (args.length - 2); i +=3 )
    if ((obj=findObj(args[i]))!=null) {
        v = args[i+2];
        if (obj.style) {
            obj.style.visibility
                = (v=='show') ? 'visible'
                : (v=='hide') ? 'hidden'
                              : v;
            obj.style.display
                = (v=='show') ? ''
                : (v=='hide') ? 'none'
                              : v;
        }
    }
}

function findObj(n, d) {
  var p,i,x;
  if(!d) d=document;
  if( (p=n.indexOf("?")) >0 && parent.frames.length ) {
    d=parent.frames[n.substring(p+1)].document;
    n=n.substring(0,p);
  }

  if(!(x=d[n]) && d.all)
    x=d.all[n];
  for (i=0; !x && i < d.forms.length; i++)
    x=d.forms[i][n];
  for (i=0; !x && d.layers && i<d.layers.length; i++)
    x=findObj(n,d.layers[i].document);

  if(!x && d.getElementById)
    x = d.getElementById(n);

  return x;
}

function e3_snap() {
    var x,y,ox,bx,oy,p,tx,a,b,k,d,da,e,el,tw,q0,xx,yy,w1,pa='px',args=e3_snap.arguments;a=parseInt(a);
    if (document.layers||window.opera) {
        pa='';
    }
    for (k=0;k<(args.length);k+=4) {
        if ((g=findObj(args[k]))!=null) {
            if ((el=findObj(args[k+1]))!=null) {
                a=parseInt(args[k+2]);b=parseInt(args[k+3]);x=0;y=0;ox=0;oy=0;p="";tx=1;
                da="document.all['"+args[k]+"']";
                if (document.getElementById) {
                    d="document.getElementsByName('"+args[k]+"')[0]";
                    if (!eval(d)) {
                        d="document.getElementById('"+args[k]+"')";
                        if (!eval(d)) {d=da;}
                    }
                } else if (document.all) {d=da;} {
                    if (document.all||document.getElementById) {
                        while(tx==1) {
                                p+=".offsetParent";
                                if (eval(d+p)) {
                                    x+=parseInt(eval(d+p+".offsetLeft"));y+=parseInt(eval(d+p+".offsetTop"));
                                } else {
                                    tx=0;
                                }
                        }
                        ox=parseInt(g.offsetLeft);oy=parseInt(g.offsetTop);tw=x+ox+y+oy;
                        if (tw==0||(navigator.appVersion.indexOf("MSIE 4")>-1&&navigator.appVersion.indexOf("Mac")>-1)) {
                            ox=0;oy=0;
                            if (g.style.left) {
                                x=parseInt(g.style.left);y=parseInt(g.style.top);
                            } else {
                                w1=parseInt(el.style.width);bx=(a<0)?-5-w1:-10;a=(Math.abs(a)<1000)?0:a;b=(Math.abs(b)<1000)?0:b;
                                x=document.body.scrollLeft+event.clientX+bx;y=document.body.scrollTop+event.clientY;
                            }
                        }
                    } else if (document.layers) {
                        x=g.x;
                        y=g.y;
                        q0=document.layers,dd="";
                        for(var s=0;s<q0.length;s++) {
                            dd='document.'+q0[s].name;
                            if (eval(dd+'.document.'+args[k])) {
                                x+=eval(dd+'.left');y+=eval(dd+'.top');
                                break;
                            }
                        }
                    }
                }
                e=(document.layers)?el:el.style;xx=parseInt(x+ox+a),yy=parseInt(y+oy+b);
                if (navigator.appVersion.indexOf("MSIE 5")>-1 && navigator.appVersion.indexOf("Mac")>-1) {
                    xx+=parseInt(document.body.leftMargin);yy+=parseInt(document.body.topMargin);
                }
                e.left=xx+pa;e.top=yy+pa;
            }
        }
    }
}

function rtk_uncheck()
{
    for (i=0;i<arguments.length;i++){
        obj = arguments[i].indexOf ? findObj(arguments[i]) : arguments[i];
        if (obj){
            obj.checked = false;
        }
    }
}

var rtk_hex_digits = "0123456789ABCDEF";
function rtk_hex(d) {
    var h = rtk_hex_digits.substr(d&15,1);
    while(d>15) {d>>=4;h=rtk_hex_digits.substr(d&15,1)+h;}
    return h;
}

function to_s(val) {
    return '' + val;
}

function rtk_arrayify(arrayoid) {
    var result = new Array();
    for(i = 0; i < arrayoid.length; ++i) {
        result.push(arrayoid[i]);
    }
    return result;
}

var needs_a_comma = /^(-?\d+)(\d{3})([,.\d]*)$/;
var thousands_separator = ',';

function rtk_commify(number) {
    var commified = to_s(number);
    var match;
    while (match = needs_a_comma.exec(commified)) {
        commified = match[1] + thousands_separator + match[2] + match[3];
    }
    return commified;
}

function modifyBookmark (outputid, url, title, getUrl, saveMessage) {
    var params = new Array;
    params.push('url=' + escape(url));
    params.push('title=' + escape(title));
    var paramStr = params.join('&');
    if(saveMessage) {
        $(outputid).innerHTML = saveMessage;
    }
    var ajax = new Ajax.Updater(outputid, getUrl, { method: 'get', parameters: paramStr });
}

function submit_button_for_form(form)
{
    var inputs = form.getElementsByTagName('input');
    for(var i = 0; i < inputs.length; ++i)
        if(inputs[i].type == 'submit')
            return inputs[i];
    return null;
}

function option_set_onchange_for_form_elements(elts)
{
    for(var j = 0; j < elts.length; ++j)
    {
        var old_onchange = elts[j].onchange;

        elts[j].onchange = option_handler_wrap(old_onchange);
        if(elts[j].tagName.toLowerCase() == 'input'
           && (elts[j].type.toLowerCase() == 'text'
               || elts[j].type == ''
               || elts[j].type == null)) {
            var old_onkeydown = elts[j].onkeydown;
            elts[j].onkeydown = option_handler_wrap(old_onkeydown);
        }
    }
}

function option_disable_go_buttons()
{
    var oc_forms = $('report-options');
    if (!oc_forms) return;

    for(var i = 0; i < oc_forms.length; ++i)
    {
        var button = submit_button_for_form(oc_forms[i]);

        Element.removeClassName( button, 'option-collection-go-button-enabled'  );
        Element.addClassName(    button, 'option-collection-go-button-disabled' );

        option_set_onchange_for_form_elements(oc_forms[i].getElementsByTagName('input'));
        option_set_onchange_for_form_elements(oc_forms[i].getElementsByTagName('select'));
    }
}

function option_enable_go_button_for(elt)
{
    if(elt && elt.form)
    {
        var button = submit_button_for_form(elt.form);
        if(button)
        {
            Element.removeClassName( button, 'option-collection-go-button-disabled' );
            Element.addClassName(    button, 'option-collection-go-button-enabled'  );

        }
    }
}

function option_handler_wrap(old_onchange)
{
    return function(ev) {
        if(old_onchange)
            old_onchange(ev);

        if(!ev) ev = window.event;

        var srcElement;
        if(ev.target) srcElement = ev.target;
        else srcElement = ev.srcElement;

        option_enable_go_button_for(srcElement);
    }
}

function update_fuzzy_number_fields(event, fuzz, precision)
{
    var elt = Event.element(event ? event : window.event);
    var basename = elt.id.replace(/_[^_]*$/, '');

    var fuzzy_input  = $(basename + '_FuzzyInputElement');
    var fuzzy_select = $(basename + '_FuzzySelectElement');
    var from_input   = $(basename + '_FromInputElement');
    var to_input     = $(basename + '_ToInputElement');

    if (elt == fuzzy_input || elt == fuzzy_select) {
        if ($F(elt) == '' || isNaN($F(elt))) {
            from_input.value = '';
            to_input.value   = '';
        } else if ($F(elt) == 'CUSTOM') {
        } else {
            var scale = Math.pow(10, precision);
            from_input.value = Math.round($F(elt) * (1-fuzz) * scale) / scale;
            to_input.value   = Math.round($F(elt) * (1+fuzz) * scale) / scale;
        }
    } else {
        if (fuzzy_input) {
            fuzzy_input.value = 'CUSTOM';
        }
        if (fuzzy_select) {
            fuzzy_select.selectedIndex = fuzzy_select.length - 1;
        }
    }
}

var treeOptionVisible = {};

function toggleTreeOption(cgi_name) {

    if (Element.hasClassName(cgi_name + '_tree_filter', 'disabled-tree-option')) {
        if(treeOptionVisible[cgi_name]) {
            Element.removeClassName(cgi_name + '_tree_filter', 'disabled-tree-option');
            toggleTreeOption(cgi_name);
            Element.addClassName(cgi_name + '_tree_filter', 'disabled-tree-option');
        }

        return;
    }

    showHideLayers(cgi_name + '_tree_option_div', '', treeOptionVisible[cgi_name] ? 'hide' : 'show');

    if ($(cgi_name + '_tree_option_selection_list_div')) {
        showHideLayers(cgi_name + '_tree_option_selection_list_div', '', treeOptionVisible[cgi_name] ? 'hide' : 'show');
        resnap_multiple_selection_list(cgi_name);

        hideShowElements($(cgi_name + '_tree_option_selection_list_div'), treeOptionVisible[cgi_name] ? '' : 'hidden');
    }

    e3_snap(cgi_name + '_tree_filter', cgi_name + '_tree_option_div', 0, tree_top_offset(cgi_name));
    hideShowElements($(cgi_name + '_tree_option_div'), treeOptionVisible[cgi_name] ? '' : 'hidden');

    if(treeOptionVisible[cgi_name])
        Element.removeClassName(cgi_name + '_tree_filter', 'treeoption-container-opened');
    else
        Element.addClassName(cgi_name + '_tree_filter', 'treeoption-container-opened');

    treeOptionVisible[cgi_name] = !treeOptionVisible[cgi_name];
}

function tree_top_offset(cgi_name) {
    if($(cgi_name + '_tree_filter').getHeight)
        return $(cgi_name + '_tree_filter').getHeight();
    else
        return $(cgi_name + '_tree_filter').clientHeight;
}

function resnap_multiple_selection_list(cgi_name) {
    var relative_left_position;
    if ($(cgi_name + '_tree_option_div').getWidth)
        relative_left_position = $(cgi_name + '_tree_option_div').getWidth();
    else
        relative_left_position = $(cgi_name + '_tree_option_div').clientWidth;
    e3_snap(cgi_name + '_tree_filter', cgi_name + '_tree_option_selection_list_div', relative_left_position, tree_top_offset(cgi_name));
}

function showTreeOption(cgi_name) {
    if(!treeOptionVisible[cgi_name])
        toggleTreeOption(cgi_name);
}

function hideTreeOption(cgi_name) {
    if(treeOptionVisible[cgi_name])
        toggleTreeOption(cgi_name);
}

function selectTreeItem(cgi_name, desc, value) {
    $(cgi_name + '_tree_filter').innerHTML = desc;

    var split_char = "~";
    if (value.indexOf(split_char) > 0) {
        $(cgi_name).name = value.substr(0,value.indexOf(split_char));
        value = value.substr(value.indexOf(split_char)+1);
    } else {
        $(cgi_name).name = cgi_name;
    }

    $(cgi_name).value = value;

    if ($(cgi_name).onchange) {
        $(cgi_name).onchange();
    }

    showHideLayers(cgi_name + '_tree_option_div', '', 'hide');
    hideShowElements($(cgi_name + '_tree_option_div'), '');
    treeOptionVisible[cgi_name] = false;

    if (window.activate_go_button_for_form) {
        activate_go_button_for_form($(cgi_name + '_tree_filter_key_proxy').form);
    }
}

function selectDateTreeItem(cgi_name, desc, value) {
    $(cgi_name + '_tree_filter').innerHTML = desc;
    var range = value.split('_');
    if (range.length == 2) {
        $(cgi_name + '_from_date').value = range[0];
        $(cgi_name + '_to_date').value = range[1];
        $(cgi_name).value = '';
    } else {
        $(cgi_name + '_from_date').value = '';
        $(cgi_name + '_to_date').value = '';
        $(cgi_name).value = value;
    }
    showHideLayers(cgi_name + '_tree_option_div', '', 'hide');
    hideShowElements($(cgi_name + '_tree_option_div'), '');
    treeOptionVisible[cgi_name] = false;
    if (window.go_button_activate)
        go_button_activate();
}

function selectDateRangeTreeItem(cgi_name, desc, value) {
    $(cgi_name + '_tree_filter').innerHTML = desc;
    var range = value.split('_');
    if (range.length == 2) {
        $(cgi_name + '_from_date').value = range[0];
        $(cgi_name + '_to_date').value = range[1];
        $(cgi_name).value = 'RANGE';
    } else {
        $(cgi_name + '_from_date').value = '';
        $(cgi_name + '_to_date').value = '';
        $(cgi_name).value = value;
    }
    showHideLayers(cgi_name + '_tree_option_div', '', 'hide');
    hideShowElements($(cgi_name + '_tree_option_div'), '');
    treeOptionVisible[cgi_name] = false;

    if (window.go_button_activate)
        go_button_activate();
}

function updateHideShowColumns (outputid, report_id, hideShowColumnForm, getUrl, redirectUrl, shouldRedirect) {
    var getUrl = '/admin/hide_show_columns_updater.html';
    var params = new Array;

    shouldRedirect = shouldRedirect || !!document.all;

    params.push('report_id=' + escape(report_id));
    if(shouldRedirect) params.push('_redirect=' + escape(redirectUrl));
    for (var i = 0; i < hideShowColumnForm.length; i++) {
        var elt = hideShowColumnForm[i];
        if (elt.checked) {
            params.push(elt.name + '=' + elt.value); // add to paramStr to save to db
        }
    }
    var paramStr = params.join('&');
    if(shouldRedirect)
        document.location.replace(getUrl + '?' + paramStr);
    else
        new Ajax.Updater(outputid, getUrl, { method: 'get', parameters: paramStr });
}

function resetHideShowColumns(outputId, reportId, hideShowColumnForm, getUrl, redirectUrl, shouldRedirect)
{
    var getUrl = '/admin/hide_show_columns_updater.html';
    var params = new Array;

    params.push('reset=Y');
    params.push('report_id=' + escape(reportId));

    if (shouldRedirect) {
        params.push('_redirect=' + escape(redirectUrl));
    }

    var paramStr = params.join('&');

    if (shouldRedirect) {
        document.location.replace(getUrl + '?' + paramStr);
    }
    else {
        new Ajax.Updater(outputId, getUrl, { method: 'get', parameters: paramStr });
    }
}

function hideShowReportColumnsFromFormInputs() {
    var formElement = document.getElementById('hide-show-form');
    for (var i = 0; i < formElement.length; i++) {
        var input = formElement.elements[i];
        if (input.type == 'radio') {
            if (input.checked) {
                var columns = input.name.split(',');
                for (var j = 0; j < columns.length; j++) {
                    if (input.value == 1) {
                        hideShowReportColumn(columns[j], '');// show this column
                    }
                    else {
                        hideShowReportColumn(columns[j], 'none');// hide this column
                    }
                }
            }
        }
    }
}

function hideShowReportColumn(columnName, displayValue) {
    var columnElements = document.getElementsByName('column-name-' + columnName);
    var widthValue = displayValue == 'none' ? '0' : 'auto';

    for (var j = 0; j < columnElements.length; j++) {
        columnElements[j].style.display = displayValue;
        columnElements[j].style.width = widthValue;
    }
}

function suggestive_list_results_focus(suggestion_name)
{
    suggestive_list_show_results(suggestion_name);
    $(suggestion_name + '-results')._focused = true;
    return true;
}

function suggestive_list_search_focus(suggestion_name, cgi_name)
{
    var suggestion_selector = $(suggestion_name + '-results');
    suggestion_selector.parentNode.removeChild(suggestion_selector);
    $(cgi_name + '-search').parentNode.appendChild(suggestion_selector);
    $(cgi_name + '-search')._focused = true;

    suggestive_list_show_results(suggestion_name, cgi_name);
    suggestive_list_update_results(suggestion_name, cgi_name);
    return true;
}

function suggestive_list_results_blur(suggestion_name)
{
    $(suggestion_name + '-results')._focused = false;
    setTimeout(function() { suggestive_list_hide_results_if_appropriate(suggestion_name) }, 100);
    return true;
}

function suggestive_list_search_blur(suggestion_name, cgi_name)
{
    $(cgi_name + '-search')._focused = false;
    setTimeout(function() { suggestive_list_hide_results_if_appropriate(suggestion_name) }, 100);
    return true;
}

function suggestive_list_show_results(suggestion_name, cgi_name)
{
    $(suggestion_name + '-results').parentNode.style.zIndex = 150;
    $(suggestion_name + '-results').style.display = 'inline';
    if (cgi_name) {
        $(suggestion_name + '-results')._target_cgi_name = cgi_name;
        $(cgi_name + '-search')._orig_value = $(cgi_name + '-search').value;
    }
}

function suggestive_list_hide_results_if_appropriate(suggestion_name)
{
    if (!$(suggestion_name + '-results')._focused
        && !$($(suggestion_name + '-results')._target_cgi_name + '-search')._focused)
        suggestive_list_hide_results(suggestion_name);
}

function suggestive_list_hide_results(suggestion_name)
{
    $(suggestion_name + '-results').parentNode.style.zIndex = 100;
    $(suggestion_name + '-results').style.display = 'none';
    suggestive_list_reset_value(suggestion_name);
}

function suggestive_list_reset_value(suggestion_name)
{
    var cgi_name = $(suggestion_name + '-results')._target_cgi_name;
    if (cgi_name) {
        $(cgi_name + '-search').value = $(cgi_name + '-search')._orig_value;
    }
}

function suggestive_list_search_keydown(suggestion_name, cgi_name, evt)
{
    if(window.event)
        evt = event;
    var code = evt.keyCode || evt.which;

    switch(code) {
    case 40: //down arrow
        $(suggestion_name + '-results').focus();
        return false;
    }
    return true;
}

function suggestive_list_results_keydown(suggestion_name, evt)
{
    if(window.event)
        evt = event;
    var code = evt.keyCode || evt.which;

    switch(code) {
    case 10:
    case 13: //return
        suggestive_list_update_value(suggestion_name);
        return false;
    }
    return true;
}

function suggestive_list_results_click(suggestion_name, evt)
{
    suggestive_list_update_value(suggestion_name);
    return false;
}

function suggestive_list_update_value(suggestion_name)
{
    var suggestion_selector = $(suggestion_name + '-results');
    var value = $(suggestion_name + '-results').value;
    if (!value)
        return true;

    $(suggestion_selector._target_cgi_name + '-search')._updating_value = true;
    $(suggestion_selector._target_cgi_name).value = value;

    var possibilities = suggestive_list_possibilities[suggestion_name];

    for (var i = 0; i < possibilities.length; ++i)
        if (possibilities[i][0] == value) {
            $(suggestion_selector._target_cgi_name + '-search').value = possibilities[i][1];
            $(suggestion_selector._target_cgi_name + '-search')._orig_value = possibilities[i][1];
            break;
        }
    return true;
}

var SUGGESTIVE_LIST_MAX_MATCHES = 20;

function suggestive_list_matches(option, search)
{
    for(var i = 0; i < search.length; ++i)
        if (option.toLowerCase().indexOf(search[i]) < 0)
            return false;
    return true;
}

function suggestive_list_update_results(suggestion_name, cgi_name)
{
    if ($(cgi_name + '-search')._updating_value) {
        $(cgi_name + '-search')._updating_value = false;
        return;
    }

    var search_string = $(cgi_name + '-search').value;
    var search_words = search_string.toLowerCase().split(' ');
    var possibilities = suggestive_list_possibilities[suggestion_name];
    var matches = [];
    var old_value = $(suggestion_name + '-results').value;

    if (search_string != '')
        for (var i = 0; i < possibilities.length - 1; ++i) {
            if (suggestive_list_matches(possibilities[i][1], search_words)) {
                if (matches.length > SUGGESTIVE_LIST_MAX_MATCHES) {
                    matches.push(['', '. . .']);
                    break;
                }
                matches.push(possibilities[i]);
            }
        }

    var results = $(suggestion_name + '-results');
    while(results.hasChildNodes())
        results.removeChild(results.firstChild);

    for (var i = 0; i < matches.length; ++i) {
        var result = document.createElement('option');
        result.value = matches[i][0];
        if (old_value && old_value == matches[i][0])
            result.selected = "selected";
        result.appendChild(document.createTextNode(matches[i][1]));
        results.appendChild(result);
    }

    return true;
}

function browser_version() {
    var v = parseFloat(navigator.appVersion);

    if (browser_is_ie()) {
        if (v > 4) {
            return v;
        }

        var rx = new RegExp('msie ([0-9]+\.[0-9]+)','i');
        var match = rx.exec(navigator.userAgent);
        if (match) {
            return match[1];
        }
    }

    return v;
}

function browser_is_ie() {
    return navigator.userAgent.toLowerCase().indexOf("msie") > -1;
}
