/* SVN File $Id: coresoft.js 727 2009-11-18 11:23:45Z marc $ */

$.fn.jsonSelect = function(options) {
    var el = $(this);
    el.change(function(){
        // get the new value
        var new_val = $(this).val();
        //make child select empty
        $(options.child).html(( options.empty && options.empty != false ? options.empty : '<option value=""></option>' ));

        var url = options.source;
        if ( new_val  == '' && options.empty_source && options.empty_parent )
        {
            url = options.empty_source;
            // parent is given by the specified field's value or the parameter value itself in case it's not the id of an element
            new_val = ( $(options.empty_parent).length ? $(options.empty_parent).val() : $(options.empty_parent) );
        }
        if ( new_val != '' )
        {
            $.getJSON(url + new_val, function(data){
                $(options.child).empty();
                if(options.empty && options.empty != false)
                    $(options.child).append(options.empty);

                $.each(data, function(optionsIndex, option){
                    var opt = "<option value=\"" + optionsIndex + "\">" + option + "</option>";
                    $(options.child).append(opt);
                });
            });
        }
        // if the child's select exit, trigger the on change event for it
        if ( $(options.child).length )
            $(options.child).change();
    });
    // load depending list when empty either on page load
    if ( $('option[value!=]', options.child).length == 0 )
        $(this).change();
}

function setGlobalAjaxWait( init )
{
    if ( init )
    {
        if ( parseFloat($.fn.jquery) < 1.4 )
            $().ajaxStart($.blockUI).ajaxStop($.unblockUI);
        else
            $(document).ajaxStart($.blockUI).ajaxStop($.unblockUI);
    }
    else
    {
        if ( parseFloat($.fn.jquery) < 1.4 )
            $().unbind('ajaxStart', $.blockUI).unbind('ajaxStop', $.unblockUI);
        else
            $(document).unbind('ajaxStart', $.blockUI).unbind('ajaxStop', $.unblockUI);
    }
}

function flashMessage(selector)
{
        $('div#flashMessage').dialog({ hide: 'fade', closeOnEscape: true, width: 'auto', minHeight: 0, dialogClass: 'no-title', resizable: false });
        setTimeout('$("div#flashMessage").dialog("close")', 3000);
}

jQuery(document).ready(function()
{
    flashMessage();
    $('#show_flash').mouseover(flashMessage);

    $.blockUI.defaults.message = $("#waitdiv");
    setGlobalAjaxWait(true);

    $("#modaledit" ).dialog({
            autoOpen: false,
            height: 300,
            width: 350,
            modal: true,
            buttons: {
                "OK": function() { /*do something */ $( this ).dialog( "close" ); },
                Cancel: function() { $( this ).dialog( "close" ); }
            },
            close: function() {}
        });

    $('input[date_selects]').datepicker({
        beforeShow: readLinked, onSelect: updateLinked,
        buttonImage: pathToImages+'calendar.png', showOn: 'button', buttonImageOnly: true,
        changeMonth: true, changeYear: true, showButtonPanel: true });

    if ( $('dl.description > dt').length > 1 )
    {
        $('dl.description > dt').live  ('click', function(evt) { $(this).next().toggle('slow'); $(this).children('span').toggle(); })
                                .each(function (i) {
                                    if ( $(this).next().is(':visible') )
                                        $(this).append('<span class="collapse">&uArr;</span><span class="expand" style="display:none">&dArr;</span>');
                                    else
                                        $(this).append('<span class="collapse" style="display:none">&uArr;</span><span class="expand">&dArr;</span>');
                                    });

        $('dl.description > div > a.collapseall').live('click', function(evt) {
            evt.preventDefault();
            $(this).parent().nextAll('dd').hide();
            $(this).parent().nextAll('dt').children('span.expand').show();
            $(this).parent().nextAll('dt').children('span.collapse').hide();
        });
        $('dl.description > div > a.expandall').live('click', function(evt) {
            evt.preventDefault();
            $(this).parent().nextAll('dd').show();
            $(this).parent().nextAll('dt').children('span.expand').hide();
            $(this).parent().nextAll('dt').children('span.collapse').show();
        });
    }

    $('input.integer').numeric();
    $('input.uinteger').numeric({signed: false});
    $('input.decimal').numeric({ float: true });

    $('input.percentage').each( function (i) { $(this).focus(); $(this).val( parseFloat($(this).val()) * 100.0); $(this).blur(); } )
                         .numeric({ float: true })
                         .change( function(evt) { $(this).focus(); if ( parseFloat($(this).val()) > 100.0 ) { $(this).val('100'); }; $(this).blur(); } );

    // bind the submit of forms containing numeric fields to parse their values (for the ones having a value)
    // removes all formatting to leave the numeric value only
    $('input.integer, input.uinteger, input.decimal, input.percentage').parents('form').submit( function () {
        var formElt = $(this);
        $('input.integer[value!=], input.uinteger[value!=], input.decimal[value!=]', formElt).each( function() {
            if ( !$(this).hasClass('noformat') )
                $(this).val($(this).parseNumber({ locale: _locale, format: ( $(this).hasClass('integer') || $(this).hasClass('uinteger') ? '#,###' : '#,###.00' ) })).removeAttr('parsed');
        } );
        $('input.percentage[value!=]', formElt).each( function() {
            if ( !$(this).hasClass('noformat') )
                $(this).val( $(this).parseNumber({ locale: _locale, format: '#,###.00' }) / 100.0 ).removeAttr('parsed');
            else
                $(this).val( $(this).val() / 100.0 );
        } );
        return true;
    } );

    // jquery UI button / buttonset; use with cake, see pages/test.ctp
    $('.ui_button').each( function(i) { $(this).button({ icons: { primary: $(this).attr('lefticon'), secondary: $(this).attr('righticon') }, text: ( $(this).attr('notext') == undefined ) }) });
    $('.ui_buttonset').buttonset();


    // set the focus on first input of first form that's not the search form
    if ( $(':input.form-error').length == 0 )
        $(':input', 'form:not([id*=Search]):first').not(':hidden').not(':disabled').first().focus().select();
    else
        $(':input.form-error:first').focus().select();

    // special things for ie6,ie7 and previous: don't know inline-block, so fake it for actions menus wider than the view
    if ( jQuery.browser.msie && jQuery.browser.version < 8 && $('div.actions ul').length > 0 )
    {
        $('div.actions ul').each( function (i) {
            var pos1= $('li:first', $(this)).offset()
            var pos = $('li:last', $(this)).offset();
            var w   = $(this).outerWidth(true);
            if( (pos.left - pos1.left + $('div.actions ul li:last').outerWidth(true)) > w )
            {
                var el = $('li:first', $(this));

                while( (el = el.next()) && el.length )
                {
                    pos = el.offset();
                    while ( (pos.left - pos1.left) + el.outerWidth(true) <= w && el.length )
                    {
                        el = el.next();
                        pos = el.offset();
                    }
                    // if we have an element outside of the section, insert an empty <li> with display set to block
                    if ( el.length )
                        el.before('<li style="display:block; line-height: 0; margin: 0; padding:0; height: 0; font-size:1px"></li>');
                }
            }
        });
    }


    if ( typeof(jQuery.fn.elastic) == 'function' )
        $('textarea.elastic').elastic();

    // --- Tab handling ---
        // handle tab activationk
        $('a[tab]').click( function(evt) {
            evt.preventDefault();
            selectAppsTab( $(this).attr('tab') );
        });

        if ( $('a[tab]').length )
        {
            // select the first tab having an error (if any)
            if ( $('div.error-message').length > 0 && $('div.section').length > 0 )
            {
                selectAppsTab( $('div.error-message:first').parents('div.section').attr('id') );

                $('div.error-message').parents('div.section').each( function(i) {
                    $('a[tab="'+$(this).attr('id')+'"]').append('*').css({'color': "darkred", 'font-weight': "bolder"});
                });
            }
            else
            {
                var sel = ( $('a[tab].active').length ? $('a[tab].active').attr('tab') : $('a[tab]:first').attr('tab') );
                selectAppsTab( sel );
            }
        }
    // ---

    $('[height_as]').each( function(i) {
        var ident = '#' + $(this).attr('height_as');
        var h = $(ident).outerHeight();
        $(this).height( h );
        var dh = $(this).outerHeight() - h;
        if ( dh > 0 )
            $(this).height(h - dh);
    });

    $('.toggle_next').click( function(evt) { evt.preventDefault(); $(this).next().toggle('slow'); });

    // --- treeview handling ---
    $('.treeview div').filter(':even').addClass('altrow');

    $('.treeview li:has(ul) > div').addClass('parent');

    $('ul', '.treeview').each(function(i) { $('li:last', this).addClass('last'); });
    $('ul.treeview > li:last').addClass('last');

    $('.treeview div.parent').click(function(evt) {
        if ( evt.target.nodeName == 'A' || evt.target.nodeName == 'a' )
            return true;
        $(this).toggleClass('expand').next('ul').toggle();
     });

    // --- disable paste for needed fields ---
    $('.no-paste').bind('paste', function(evt) { evt.preventDefault(); });

    // --- print handling ---
    $('a[print]').click( function( evt) {
            evt.preventDefault();

            var ident = '#' + $(this).attr('print');

            // expand all sections of the report (if using dl.desctiption
            $('dl.description > dd:hidden, dl.description > dt:hidden', ident).show();

            // for tabs, we have to copy each tab before its corresponding section
            if ( $('ul.tabs', ident).length )
            {
                $('ul.tabs li a[tab]', ident).each( function(i) {
                    var section = '#' + $(this).attr('tab');
                    $('<ul class="print_tabs"><li>' + $(this).parent().html() + '</li></ul>').insertBefore(section);
                });
                $('div.section').show();
            }

            // print the report's parent div (to have report name and description and to have the style given by div.coresoft)
            $(ident).jqprint({ printContainer: false, debug: false});

            // remove the tabs added to print
            $('ul.print_tabs').remove();
            if ( $('ul.tabs', ident).length )
            {
                $('ul.tabs li a[tab][class!=active]', ident).each( function(i) {
                     var section = '#' + $(this).attr('tab');
                     $(section).hide();
                });
            }
        });
});

// Prepare to show a date picker linked to three select controls
function readLinked(pick)
{
    var elt = $(pick).attr('date_selects');

    // format the date value expected by the datepicker class
    var dateFmt = $.datepicker._defaults.dateFormat;
    var dateVal = $.datepicker._defaults.dateFormat;
    dateVal = dateVal.replace('dd', $('#'+elt+'Day').val());
    dateVal = dateVal.replace('mm', $('#'+elt+'Month').val());
    dateVal = dateVal.replace('yy', $('#'+elt+'Year').val());

    $(pick).val(dateVal);

    var options = [ 'maxDate', 'minDate', 'defaultDate', 'numberOfMonths', 'yearRange' ]
    for ( i=0; i< options.length; i++ )
    {
        var val = $(pick).attr(options[i]);
        if ( val )
        {
            // transform date values form yyyy-mm-dd to date picker's format
            if ( i < 3 )
            {
                dateVal = dateFmt;
                dateVal = dateVal.replace('dd', val.substr(8, 2));
                dateVal = dateVal.replace('mm', val.substr(5, 2));
                dateVal = dateVal.replace('yy', val.substr(0, 4));
                val = dateVal;
            }
            $(pick).datepicker('option', options[i], val);
        }
    }

    return {};
}

// Update three select controls to match a date picker selection
// But need to get rid of leading zero on day and month first
function updateLinked(t_date, pick)
{
    var elt = $(pick.input.get(0)).attr('date_selects');

    var dateFmt = $.datepicker._defaults.dateFormat;

    if ( parseFloat($.fn.jquery) < 1.4 )
    {
        $('#'+elt+'Month').val( $('#'+elt+'Month option[value='+t_date.substr(dateFmt.indexOf('mm'), 2)+']').text() ).change();
        $('#'+elt+'Day').val( $('#'+elt+'Day option[value='+t_date.substr(dateFmt.indexOf('dd'), 2)+']').text() ).change();
        $('#'+elt+'Year').val(t_date.substr(dateFmt.indexOf('yy'), 4)).change();
    }
    else
    {
        $('#'+elt+'Month').val(t_date.substr(dateFmt.indexOf('mm'), 2)).change();
        $('#'+elt+'Day').val  (t_date.substr(dateFmt.indexOf('dd'), 2)).change();
        $('#'+elt+'Year').val (t_date.substr(dateFmt.indexOf('yy'), 4)).change();
    }
}

selectAppsTab = function ( ref )
{
    $('ul.tabs a.active').removeClass('active');
    $('div.section[id]').hide();
    $('a[tab="'+ref+'"]').addClass('active');
    $('#'+ref).show();
};

$.fn.readonly = function( val ) {
    return this.each(function(i) {
        var el = $(this);
        if ( val ) {
            el.attr('readonly', 'readonly');
            if ( jQuery.browser.msie )
                el.css('background-color', '#c1c1c1');
        } else {
            el.removeAttr('readonly');
            if ( jQuery.browser.msie )
                el.css('background-color', '');
        }
    }).keydown( function(evt) { // fix for IE: backspace on a readonly field should'nt go back in navigation history
        if ( evt.keyCode == 8 && $(this).attr('readonly') )
        {
            evt.preventDefault();
            return false;
        }
        return true;
    })
}

$.fn.numeric = function(options) {
    var opt = { float: false, signed: true };
    $.extend(opt, options);

    return this.each(function(i) {
        var el = $(this);
        el.keydown ( function (evt)
          {
             var k = evt.keyCode;

             // allow all numbers always
             if ( ( k>= 48 && k <= 57 ) || ( k>= 96 && k <= 105 ) )// 0 to 9
                return ( evt.shiftKey ? false : true );

             // allow decimal point only if not already keyed in
             if ( opt.float && ( k == 190 || k == 110 ) )
             {
                var v = $(this).val();
                return ( v.indexOf('.', 0) == -1 );
             }

             // allow + or minus only at begining of string and id not already there
             if (opt.signed && ( ( evt.shiftKey && k == 107 ) || ( !evt.shiftKey && k == 109 ) ) && !$(this).hasClass('unsigned') )
             {
                var pos = $(this).caret();
                var v = $(this).val();
                if ( pos > 0 )
                    return false;
                if ( v.length == 0 )
                    return true;
                if ( v[0] != '+' && v[0] != '-' )
                    return true;
                else
                    return false;
             }

             // return true only for backspace, tab, delete, enter and escape, left and right arrows
             return ( ((k >= 65 && k <= 111) || k >= 186) ? false : true ); // allow only non typeable characters( k == 8 || k == 9 || k == 46 || k == 13 || k == 27 || k == 37 || k == 39 || k ==36 || k == 35 );
          })
          .attr('autocomplete', 'off');

        if ( !el.hasClass('noformat') )
        {
            el.css('text-align', 'right')
              .blur(function(){
                    if ( el.val() != '' )
                        $(this).formatNumber({ locale: _locale, format: ( opt.float ? '#,###.00' : '#,###' ) }).attr('parsed', 'parsed');
                })
              .focus(function(){
                    if ( el.val() != '' )
                        $(this).val($(this).parseNumber({ locale: _locale, format: ( opt.float ? '#,###.00' : '#,###' ) })).removeAttr('parsed').select();
                });

            if ( el.val() != '' )
                el.formatNumber({ locale: _locale, format: ( opt.float ? '#,###.00' : '#,###' ) });
        }
    } );
}

getNumber = function( ident)
{
    var v = 0;
    if ( ident.substr(0, 1) != '#' )
        ident = '#'+ident;

    if ( $(ident).attr('parsed') == 'parsed' )
        v = $(ident).parseNumber({ locale: _locale, format: '#,###.00' }, false);
    else
    {
        v = $(ident).val();
        v = ( v != '' ? parseFloat(v) : 0 );
    }
    return v;
};

setNumber = function( ident, v )
{
    if ( ident.substr(0, 1) != '#' )
        ident = '#'+ident;

    if ( $(ident+':input').length > 0 )
        $(ident).val(Math.round(v * 100) / 100).formatNumber({ locale: _locale, format: ( $(ident+':input').hasClass('integer') ? '#,###' : '#,###.00' ) }).attr('parsed', 'parsed');
    else
        $(ident).html(Math.round(v * 100) / 100).formatNumber({ locale: _locale, format: ( $(ident+':input').hasClass('integer') ? '#,###' : '#,###.00' ) }).attr('parsed', 'parsed');
};


//(function($) {
  $.fn.caret = function(pos) {
    var target = this[0];
    if (arguments.length == 0) { //get
      if (target.selectionStart) { //DOM
        var pos = target.selectionStart;
        return pos > 0 ? pos : 0;
      }
      else if (target.createTextRange) { //IE
        target.focus();
        var range = document.selection.createRange();
        if (range == null)
            return '0';
        var re = target.createTextRange();
        var rc = re.duplicate();
        re.moveToBookmark(range.getBookmark());
        rc.setEndPoint('EndToStart', re);
        return rc.text.length;
      }
      else return 0;
    } //set
    if (target.setSelectionRange) //DOM
      target.setSelectionRange(pos, pos);
    else if (target.createTextRange) { //IE
      var range = target.createTextRange();
      range.collapse(true);
      range.moveEnd('character', pos);
      range.moveStart('character', pos);
      range.select();
    }
  }
//})(jQuery)

$.fn.focusNextInput = function() {
    return this.each(function() {
        var fields = $(this).parents('form:eq(0),body').find('button:visible,input:visible,textarea:visible,select:visible');
        var index = fields.index( this );
        if ( index > -1 && ( index + 1 ) < fields.length ) {
            fields.eq( index + 1 ).focus();
        }
        return false;
    });
};


function ensureVisible(elem)
{
    if ( !$(elem).length )
        return;

    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    var newTop = -1;

    if ( elemTop < docViewTop )
    {
        newTop = elemTop;
    }
    else if ( elemBottom > docViewBottom )
    {
        var bottom = docViewTop + elemBottom - docViewBottom;
        newTop = ( elemTop < bottom ? elemTop : bottom );
    }

    if ( newTop != -1 )
    {
        $(window).scrollTop(newTop);
        if ( $('div#flashMessage').is(':visible') )
        {
            var top = (newTop + $(window).height() - $('div#flashMessage').parent('div.ui-dialog').height() ) / 2;
            $('div#flashMessage').parent('div.ui-dialog').css('top', top+'px');
        }
    }
}

