/*
    Document   : Kompetanse.js
    Created on : 07.sep.2009
    Author     : Scan4News
    Description:
            Inneholder generaliserte funksjoner
*/

/**
 * FUNCTION ch_activate_hidden_tools
 *
 * Kobler opp alle dom-elementene som er av klassen hidden-tool-show-trigger og
 * gir dem evnen til å aktivere/vise den skjulte raden.
 *
 * Denne funksjonen er ment å kjøres rett når siden lastes menst ch_activate_hidden_tools_connect()
 * og ch_deactivate_hidden_tools_connect() er ment på dynamisk tilførte elementer
 *
 * For å gjøre bruk av denne funksjonen trengs følgende struktur:
 *  + En tabell med
 *      - 1    <tbody> som er skjult i utgangspunktet:                          class="hidden-tool hidden"
 *      - 1    <tbody> som vises når den første er skjult:                      class="hidden-tool-pre"
 *      - 0..* <link|etc> som viser hidden-tool-pre og gjemmer hidden-tool-pre: class="hidden-tool-show-trigger"
 *      - 0..* <link|etc> som skjuler hidden-tool og viser hidden-tool-pre:     class="hidden-tool-reset-trigger"
 */
function ch_activate_hidden_tools() {

    $(".hidden-tool-show-trigger").each(function() {
        ch_activate_hidden_tools_connect(this);
    });
    
    $(".hidden-tool-reset-trigger").each(function() {
        ch_deactivate_hidden_tools_connect(this);
    });
}

/**
 * FUNCTION ch_activate_hidden_tools_connect
 *
 * Tilfører et dom-objekt evnen til å vise den skjulte tbody-element av tabellen
 */
function ch_activate_hidden_tools_connect( element ) {
    $(element).click(function( event ) {
        event.preventDefault();
        $(this).parents("table:first").find(".hidden-tool").show();
        $(this).parents("table:first").find(".hidden-tool-pre").hide();
        $(this).parents("table:first").find(".empty-list").hide();
    });
}

/**
 * FUNCTION ch_deactivate_hidden_tools_connect
 *
 * Tilfører et dom-objekt evnen til å skjule tbody-element av tabellen som ellers
 * er skjult
 */
function ch_deactivate_hidden_tools_connect( element ) {
    $(element).click(function(event){
        event.preventDefault();
        $(this).parents("table:first").find(".hidden-tool").hide();
        $(this).parents("table:first").find(".hidden-tool-pre").show();
    });
}

/**
 * FUNCTION ch_get_dbid
 *
 * Henter ut en id fra en gitt streng formatert med underscorer
 */
function ch_get_dbid( streng ) {
    var explodet = streng.split("_");
    return explodet[(explodet.length-1)];
}

/**
 * FUNCTION extractDbId
 *
 * Prøver å hente ut id-en fra et dom-element
 *
 */
function extractDbId( jqueryObject ) {
    
    if( $(jqueryObject).is("a") ) {
        return $(jqueryObject).attr('rel');
    } else {
        return ch_get_dbid($(jqueryObject).attr('id'));
    }

    return null;
}

/**
 * FUNCTION tilbakemelding_ok
 *
 * Fyller inn og viser en beskjed om at en opperasjon er fullført uten feil.
 * 
 * OBS! For at denne skal ha effekt må det allerede ligge et skjult element
 * med id-en satt til 'action_status'.
 *
 * Fjerner også alle '.error-list'-elementene
 *
 */
function tilbakemelding_ok( beskjed ) {
    $(".error-list").remove();
    $("#action_status").html(beskjed);

    $("#action_status").slideDown("fast", function() {
        $(this).fadeOut(2000);
    });
}

/**
 * FUNCTION zend_form_feilmeldinger
 *
 * Denne er spesialtilpasset for å ta i mot feilmeldinger i følgende format:
 *  [
 *      '0':[
 *              felt: 'input-id-1', 
 *              'beskjed': ['Feil 1', 'Feil 2', 'Feil n']
 *          ],
 *      '1':[
 *              felt: 'input-id-n',
 *              'beskjed': ['Feil 1', 'Feil 2', 'Feil n']
 *          ],
 *  ]
 *
 *  Leter opp aktuelt felt vha. av 'felt'-verdien og setter inn en ul-liste
 *  under input-elementet.
 *
 */
function zend_form_feilmeldinger( feilmeldinger ) {
    
    for( i=0; i < feilmeldinger.length; i++ ) {    
        var ul = $('<ul class="error-list"></ul>');
        for( j=0; j < feilmeldinger[i]['beskjed'].length; j++ ) {
            ul.append('<li>'+ feilmeldinger[i]['beskjed'][j] +'</li>');
        }

        $(ul).insertAfter("#" + feilmeldinger[i]['felt']);
    }
}
function zend_form_feilmeldinger_relative( feilmeldinger, form ) {

    for( i=0; i < feilmeldinger.length; i++ ) {
        var ul = $('<ul class="error-list"></ul>');
        for( j=0; j < feilmeldinger[i]['beskjed'].length; j++ ) {
            ul.append('<li>'+ feilmeldinger[i]['beskjed'][j] +'</li>');
        }

        $(ul).insertAfter( $(form).find("[name="+ feilmeldinger[i]['felt'] +"]:first") );
    }
}

/**
 * FUNCTION zend_form_reset
 *
 * Fjerner alle feltfeilmeldingene under en gitt form - eller alle på hele siden
 */
function zend_form_reset( form ) {

    var parent = ( form == null ) ? $('body') : form;

    $(parent).find(".error-list").remove();
}


/**
 * FUNCTION getScrollXY
 *
 * Hjelper til med å få korrekt scrolleverdier uanvhengig av browser
 *
 * @see http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
 */
function getScrollXY() {
    var scrOfX = 0, scrOfY = 0;
    if( typeof( window.pageYOffset ) == 'number' ) {
        //Netscape compliant
        scrOfY = window.pageYOffset;
        scrOfX = window.pageXOffset;
    } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
        //DOM compliant
        scrOfY = document.body.scrollTop;
        scrOfX = document.body.scrollLeft;
    } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
        //IE6 standards compliant mode
        scrOfY = document.documentElement.scrollTop;
        scrOfX = document.documentElement.scrollLeft;
    }
    return [ scrOfX, scrOfY ];
}

/**
 * FUNCTION updateText
 *
 * Fyller et element med spesifisert tekst, setter tekstens farge til grønn
 * for å indikere at oppdateringen fant sted. Etter x-antall ms vil fargen
 * returnere til det den opprinnelig var
 *
 * @deprecated Denne er nå implementert som en jQuery-plugin
 */
function updateText( target, text ) {
    
    clearTimeout($(target).data("updateTextTimeoutId"));
    $(target).css({color: '#28A728'}).text(text);
    $(target).data("updateTextTimeoutId",  setTimeout(function() {$(target).css({color: ''})}, 6000));
}

/**
 * FUNCTION removeZendFromErrors
 *
 * Fjerner alle form-errors fra en zend form
 */
function removeZendFromErrors( target_from ) {
    $(target_from).find(".error-list").remove();
}

/**
 * FUNCTION copyPrototype
 *
 * --> Ikke i bruk pr. 28.09.2009
 *
 * I jakt på en god måte å takle arv i JS hjelper denne lille funksjonen med
 * å gjøre tilgjengelig baseklassens funksjoner for avledete klasser
 *
 * I bruk:
 *
 *  function Animal() {...}
 *  function Dog() {...}
 *  copyPrototype(Dog, Animal);
 *
 * @see http://www.sitepoint.com/blogs/2006/01/17/javascript-inheritance/
 */
function copyPrototype(descendant, parent) {
    var sConstructor = parent.toString();
    var aMatch = sConstructor.match( /\s*function (.*)\(/ );
    if ( aMatch != null ) {descendant.prototype[aMatch[1]] = parent;}
    for (var m in parent.prototype) {
        descendant.prototype[m] = parent.prototype[m];
    }
};

/**
 * FUNCTION bekreftSletting
 *
 * Spør bruker om han/hun er sikker på at slettingen skal utføres. Bekrefter
 * brukeren slettingen kalles callbackfunksjonen som da skal inneholde logikkgen
 * for å håndtere selve slettingen.
 */
function bekreftSletting( callback ) {
    
        if(typeof($("#delete_dialog").data('dialog')) == "undefined") {
            $("#delete_dialog").dialog({
                    bgiframe: true,
                    resizable: false,
                    autoOpen: false,
                    height:140,
                    modal: true,
                    overlay: {
                            backgroundColor: '#000',
                            opacity: 0.5
                    }
            });
        }

        $("#delete_dialog").dialog('option' , 'buttons', {
                    'Forstått, fjern elementet': function() {
                           // Forsett sletting
                           callback();
                           $(this).dialog('close');
                    },
                    'Avbryt': function() {
                            $(this).dialog('close');
                    }
                });
        

        $("#delete_dialog").dialog('open');        
}

/**
 * FUNCTION ch_getSelected
 *
 * Travarserer en selected-liste og putter verdiene inn i et array
 */
 function ch_getSelected( context ) {

     var selected = [];

     $( context ).find("input:checked").each(function() {
        selected.push( $(this).val() );
     });

     if(selected.length == 1) {
         return selected[0];
     }

     return selected;
 }

 function hentEldrefunction( linkContext, type ) {

    if( type == null ) {
        type = 'kommentar';
    }

    $.ajax({
        url: $(linkContext).attr('href'),
        success: function( html ) {
            /* Linken fjernes fra DOM */

            var hrElement = $("<hr />").insertAfter(linkContext);
            $(linkContext).remove();

            /* Appender innkommende html-struktur med eldre kommentar  */
            $(hrElement).parent().append( html );

            $(hrElement).nextAll(".kildekommentar").each(function() {
                /* Kobler opp */
                $(this).data("kommentarHelper", new KommentarOpprinnelig( this, null, type ));
            });

            $('html, body').animate({
                scrollTop: $(hrElement).offset().top
            }, 1500);

            /* Til slutt må vi koble en eventuelt hent-eldre-link, om den
             * er satt i innkommende html-struktur */
            $(hrElement).parent().children(".getOlder").click(function(event) {
                event.preventDefault();
                hentEldrefunction( this, type );
                return false;
            });
        },
        error: function() {
            feedbackHelper.showError("Det oppstod en feil ved henting av ny kommentar");
        }
    });
}

function ch_isEmpty(ob){
   for(var i in ob){return false;}
  return true;
}

// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/encodeURIComponent#Description
function urlEncode( s ) {
  return encodeURIComponent( s ).replace( /\%20/g, '+' ).replace( /!/g, '%21' ).replace( /'/g, '%27' ).replace( /\(/g, '%28' ).replace( /\)/g, '%29' ).replace( /\*/g, '%2A' ).replace( /\~/g, '%7E' );
}
function urlDecode( s ) {
  return decodeURIComponent( s.replace( /\+/g, '%20' ).replace( /\%21/g, '!' ).replace( /\%27/g, "'" ).replace( /\%28/g, '(' ).replace( /\%29/g, ')' ).replace( /\%2A/g, '*' ).replace( /\%7E/g, '~' ) );
}

/**
 * Setter inn / erstatter html-innholdet til et element med en lastingsanimasjon
 *
 * @param placeholder   Må være et jQuery object
 */
function injectLoadingAnimation( placeholder ) {
    $(placeholder).html(
        "<img src='/design/grafikk/element/kbn_loading.gif' style='display:block; margin: 20px auto' />"
    );
}

/**
 * Class S4nTab
 *
 * @deprecated: Bruk snTabs istede!
 *
 * Hjelpeklasse for å initialisere ulike typer widgets på en hurtig og effektiv
 * måte.
 *
 */
function S4nTab( options ) {

    var settings = $.extend( {
        mainTabsContainer: "",
        mainTabsContainerFilter: "li",
        mainTabsContainerOnSelected: function(event, ui) {
            //
            // Vi må trigge linken manuelt siden li-elementet sluker eventen
            $(ui.selected).children("a:first").trigger("click");
        }
    }, options );

    if( settings.mainTabsContainer ) {
        $(settings.mainTabsContainer).selectable( {
            filter: settings.mainTabsContainerFilter,
            selected: settings.mainTabsContainerOnSelected
        });
    }

    for(i=0; i < settings.tabs.length; i++) {
        var tabConfig = settings.tabs[i];
        
        (function( tabConfig ) {

            var triggerSelector = "." + tabConfig.name + "-trigger";
            
            // Aktiverer triggerene
            $( triggerSelector ).click(function( event ) {
                event.preventDefault();
                
                var mc = this;

                //
                // I tilfellene en tab-visning er aktivert fra andre plasser enn under
                // hoved-tab-aktiverere (gitt under "#mainTabsContainer") må vi manipulere
                // selectable manuelt
                if( settings.mainTabsContainer &&  !$(settings.mainTabsContainer).find("*").filter(function() {return this == mc;}).length ) {
                    $(settings.mainTabsContainer).find(".ui-selectee").removeClass('ui-selected');
                    $(settings.mainTabsContainer).find(triggerSelector).parent().addClass('ui-selected');
                }

                //
                // Gjemmer alle panelene
                $(settings.panelContainer).children().hide();

                //
                // Viser ønsket
                var tabPanel = $("#" + tabConfig.name + "-panel" );
                tabPanel.show();
                if( $.isFunction(tabConfig.onSelect) ) {
                    tabConfig.onSelect();
                    tabConfig.onSelect.call(tabPanel);
                }


                return false;
            });
        })(tabConfig);
        
    }

}

/**
 * Ordinær videresending
 *
 * @var redirectUrl
 */
function redirect( redirectUrl ) {

    var href = redirectUrl;

    if( redirectUrl.match(/\/$/) ) {
        href = redirectUrl.substr(0, redirectUrl.length-1);
    }

    top.location.href = href;
}

/**
 * Brukes til å prefikse en verdi med null hvis lengden er 1
 */
function zeroPad(n) {
	return (n < 10 ? '0' : '') + n;
}

/**
 *  Returnerer datodelen av et Date-objekt i formatet hh:MM:ss
 *
 * @return string
 */
function getTimePart( date, withSeconds ) {

    var time = zeroPad(date.getHours()) +":"+  zeroPad(date.getMinutes());
    if( withSeconds ) {
        time = time + ":" + zeroPad(date.getSeconds());
    }
    return time
}

/**
 * Debug funksjon som fjerner html og erstatter med htmlentiteter
 */
function stripHtml(s) {
    return s.replace(/\\&/g, '&amp;').replace(/\\</g, '&lt;').replace(/\\>/g, '&gt;').replace(/\\t/g, '&nbsp;&nbsp;&nbsp;').replace(/\\n/g, '<br />');
}

/**
 * Function : dump()
 * Arguments: The data - array,hash(associative array),object
 *    The level - OPTIONAL
 * Returns  : The textual representation of the array.
 * This function was inspired by the print_r function of PHP.
 * This will accept some data as the argument and return a
 * text that will be a more readable version of the
 * array/hash/object that is given.
 * Docs: http://www.openjs.com/scripts/others/dump_function_php_print_r.php
 */
function dump(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;

	//The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += "    ";

	if(typeof(arr) == 'object') { //Array/Hashes/Objects
		for(var item in arr) {
			var value = arr[item];

			if(typeof(value) == 'object') { //If it is an array,
				dumped_text += level_padding + "'" + item + "' ...\n";
				dumped_text += dump(value,level+1);
			} else {
				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
			}
		}
	} else { //Stings/Chars/Numbers etc.
		dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
}

/**
 * Kombinerer en string og indeksen inn i et array
 *
 * @param {string}  value
 * @param {int}     from
 * @param {int}     to
 * @return {Object}
 */
function stringSerie( value, from, to ) {
    var array = [];

    for( var i=from; i <= to; i++ ) {
        array.push( value + i );
    }
    return array;
}


/*
 * Ui: snTabBox
 *
 * Forenklet tab-widget med mer direkte kontroll over klikk og essensielle hendelser
 *
 * Depends:
 *	ui.core.js
 */
(function($) {
    $.widget("sn.snTabBox", {
        _init: function() {
            var self = this;
            this.$tabs = self.element.children("ul.tabs:first");
            this.$panels = self.element.children("div.content");

            this.$tabs.find("a").click( function( event ) {
                event.preventDefault();
                self.selectTab( $(this) );
                return false;
            });
        },
        selectTab: function( tabToSelect ) {
            var self = this;

            // Håndter tabber
            this.$tabs.children().removeClass("active");
            $(tabToSelect).parent().addClass("active");

            //
            // Håndter paneler
            this.$panels.children().hide();
            $( $(tabToSelect).attr('href') ).show();
        }
    });

    $.extend($.sn.snTabBox, {
        defaults: {}
    });

})(jQuery);

