
jQuery.fn.fadeOutOrHide = function(duration, callback ){ return this.fadeOutOrHideEx( false, duration, callback ); };
jQuery.fn.fadeOutOrHideEx = function(isToggle, duration, callback){
    if( 0 == duration || undefined === duration )
        return this.hide( callback );
    else
    {
        this.children().each(function(){
            if(!isToggle || !$(this).hasClass('ignore_fade_toggle'))
                $(this).fadeOut(duration);
        });
        return this.fadeOut( duration, callback );
    }
};

jQuery.fn.fadeInOrShow = function(duration, callback ){ return this.fadeInOrShowEx( false, duration, callback ); };
jQuery.fn.fadeInOrShowEx = function(isToggle, duration, callback){
    if( 0 == duration ||undefined === duration )
        return this.show( callback );
    else
    {
        this.children().each(function(){
            if(!isToggle || !$(this).hasClass('ignore_fade_toggle'))
            $(this).fadeIn(duration);
        });
        return this.fadeIn( duration, callback );
    }
};

jQuery.fn.fadeInIf = function( condition, fadeOutIfFalse, duration, fadeOutDuration, callback){
    if( undefined === fadeOutDuration )
        fadeOutDuration = duration;

    if( condition )
        return this.fadeInOrShow(duration, callback);
    else
    if( fadeOutIfFalse )
        return this.fadeOutOrHide(fadeOutDuration, callback)
};

jQuery.fn.fadeToggle = function(duration, callback) {
    if( this.hasClass('hidden') )
        this.removeClass('hidden').hide();

    if( this.is(':visible') )
        return this.fadeOutOrHideEx( true, duration, callback);
    else
       return this.fadeInOrShowEx( true, duration, callback);
};



jQuery.fn.addClassIf = function( condition, removeClassIfFalse, clss ){
    if( condition )
        this.addClass( clss );
    else
    if( removeClassIfFalse )
        this.removeClass( clss);
};

jQuery.fn.genericToggle = function ( stateA, stateB, getStateValue, setStateValue, stateA_callback, stateB_callback )
{
    if( stateA == getStateValue(this) )
    {
        setStateValue( this, stateB );
        if( undefined !== stateA_callback && null != stateA_callback )
            stateA_callback();
    }
    else
    {
        setStateValue( this, stateA );
        if( undefined !== stateB_callback && null != stateB_callback )
            stateB_callback();
    }

    return this;
};

jQuery.fn.toggleText = function( textA, textB, textA_callback, textB_callback )
{
    return this.genericToggle( textA.trim(), textB.trim(),
            function(item){return item.text();},
            function(item, value){item.text(value);},
            textA_callback, textB_callback );
};

jQuery.fn.toggleValue = function( valueA, valueB, valueA_callback, valueB_callback )
{
    return this.genericToggle( valueA.trim(), valueB.trim(),
            function(item){return item.val();},
            function(item, value){item.val(value);},
            valueA_callback, valueB_callback );        
};

jQuery.fn.toggleData = function( key, valueA, valueB, valueA_callback, valueB_callback )
{
    return this.genericToggle( valueA.trim(), valueB.trim(),
            function(item){return item.data( key ); },
            function(item, value){item.data( key, value);},
            valueA_callback, valueB_callback );
};