/*-------------------------------------------------------------------- 
Scripts for creating and manipulating custom menus based on standard <ul> markup
Version: 3.0, 03.31.2009

By: Maggie Costello Wachs (maggie@filamentgroup.com) and Scott Jehl (scott@filamentgroup.com)
    http://www.filamentgroup.com
    * reference articles: http://www.filamentgroup.com/lab/jquery_ipod_style_drilldown_menu/
        
Copyright (c) 2009 Filament Group
Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
--------------------------------------------------------------------*/


var allUIMenus = [];

/* Function used to initialize the menu on a specified content-element */
$.fn.menu = function(options)
{
     var caller = this;
//     var caller = $(div_id);
    var options = options;
    var m = new Menu(caller, options);
    allUIMenus = m;
    m.init();
};

/**
* Constructor des Menus.
* @param caller Caller ist das Element auf den das Menu angewandt wird [$(caller).menu(...)]
* @param options Die Optionen die an das Menu uebergeben werden
*/
function Menu(caller, options)
{
    var menu = this;
    /*var caller = $(caller);    */
    var container = $(caller);
    this.toplist = null;
    
    /* Optionen und Defaults verschmelzen, damit fuer alles werte vorhanden sind */
    var options = jQuery.extend({        
        initial_params: {},
        
        content: null,
        width: 180, // width of menu container, must be set or passed in to calculate widths of child menus
        maxHeight: 0, // max height of menu (if a drilldown: height does not include breadcrumb)
        positionOpts: {
            posX: 'left', 
            posY: 'bottom',
            offsetX: 0,
            offsetY: 0,
            directionH: 'right',
            directionV: 'down', 
            detectH: true, // do horizontal collision detection  
            detectV : true, // do vertical collision detection
            linkToFront: false
        },
        showSpeed: 200, // show/hide speed in milliseconds
        callerOnState: 'ui-state-active', // class to change the appearance of the link/button when the menu is showing
        loadingState: 'ui-state-loading', // class added to the link/button while the menu is created
        linkHover: 'ui-state-hover', // class for menu option hover state
        linkHoverSecondary: 'li-hover', // alternate class, may be used for multi-level menus		
    // ----- multi-level menu defaults -----
        crossSpeed: 200, // cross-fade speed for multi-level menus
        crumbDefaultText: 'Teilnehmer&nbsp;alphabetisch',
        backLink: false, // in the ipod-style menu: instead of breadcrumbs, show only a 'back' link
        backLinkText: 'Zurueck',
        flyOut: false, // multi-level menus are ipod-style by default; this parameter overrides to make a flyout instead
        flyOutOnState: 'ui-state-default',
        nextMenuLink: 'ui-icon-triangle-1-e', // class to style the link (specifically, a span within the link) used in the multi-level menu to show the next level
        topLinkText: 'Alle&nbsp;&#187;',
        nextCrumbLink: 'ui-icon-carat-1-e'	
    }, options);
    
    
    /* 
     * Setzt ein Submenu auf den originial-zustand
     */
    this.resetChildMenu = function(elem)
    {
        elem
            .removeClass('fg-menu-scroll')
            .removeClass('fg-menu-current')
            .height('auto');
    }
    
    /*
     * Setzt das Drill-Down-Menu wieder auf den Anfangsstand (Also erste menuebene)zurueck
     * ???
     */
    this.resetDrilldownMenu = function()
    {
        container.find('.fg-menu-current').removeClass('fg-menu-current');
        menu.toplist.animate({ left: 0 }, options.crossSpeed, function()
        {
            $(this).find('ul').each(function(){
                $(this).hide();
                menu.resetChildMenu($(this));                
            });
            menu.toplist.addClass('fg-menu-current');            
        });     
        
        $('.fg-menu-all-lists').find('span').remove();  
        this.breadcrumb.empty().append(this.crumbDefaultHeader);      
        $('.fg-menu-footer').empty().hide();    
        menu.checkMenuHeight(this.toplist);       
    };
    
    
    /*
     * Prueft die Hoehe eines Menus und passt es gegenebfalls an
     */
    this.checkMenuHeight = function(el)
    {
        if (el.height() > options.maxHeight && options.maxHeight > 0)
            el.addClass('fg-menu-scroll');
        //el.css({ height: options.maxHeight });
        el.css({height:'auto'});
    };
    
    
    /*
     * Die Funktion initalisiert das Menu und laedt die erste Toplevel-Menustruktur
     */
    this.init = function()
    {
        /* Daten laden das Toplevel-Menu initialisieren.
         * (CSS-Klassen fuer COntainer/Toplevelmenu, breadcrumbs usw.)
         */
        menu.load(container, options.url, options.initial_params, function()
        {
            menu.toplist = container.find('ul');
            
            // Container initialisieren (Hauptsaechlich CSS)
            container
                .addClass("fg-menu-container ui-widget ui-widget-content ui-corner-all fg-menu-ipod")
                .css({ width: options.width });
        
            // Das Bread-Crumb-Menu/Backlink hinzufuegen
            menu.breadcrumb = $('<ul class="fg-menu-breadcrumb ui-widget-header ui-corner-all ui-helper-clearfix"></ul>');
            menu.crumbDefaultHeader = $('<li class="fg-menu-breadcrumb-text">' + options.crumbDefaultText + '</li>');
            var firstCrumbText = (options.backLink) ? options.backLinkText : options.topLinkText;
            var firstCrumbClass = (options.backLink) ? 'fg-menu-prev-list' : 'fg-menu-all-lists';
            var firstCrumbLinkClass = (options.backLink) ? 'ui-state-default ui-corner-all' : '';
            var firstCrumbIcon = (options.backLink) ? '<span class="ui-icon ui-icon-triangle-1-w"></span>' : '';
            menu.firstCrumb = $('<li class="'+firstCrumbClass+'"><a href="#" class="'+firstCrumbLinkClass+'">'+firstCrumbIcon+firstCrumbText+'</a></li>');
            
            if(options.backLink)
                menu.breadcrumb.addClass("fg-menu-footer").appendTo(container).hide();
            else
                menu.breadcrumb.addClass("fg-menu-header").prependTo(container);
            menu.breadcrumb.append(menu.crumbDefaultHeader);
        
            // toplist anpassen
            menu.toplist
                .addClass('fg-menu fg-menu-content fg-menu-current ui-widget-content ui-helper-clearfix')
                .css({left:0, width: container.width()});
            menu.checkMenuHeight(menu.toplist);            
        });
    }
    
    
    /*
     * Die Funktion waehlt ein Submenu aus. Falls das Menu noch nicht geladen ist werden vorher alle 
     * benoetigten Daten geladen und verarbeitet. 
     * Anschliessend wird das Submenu angezeigt
     * 
     * `node`
     *      Der Node der den Switch ausgeloest hat (A-Tag innerhalb eines Menues)
     * `params`
     *      Die Parameter die an die URl uebergeben werden sollen, wenn die daten noch nicht geladen wurden
     */
    this.select = function(node, params)
    {
        var menu = this;
        var menu_container = $(node).parent();
        
        // Wenn der Knoten noch nicht geladen wurde, dann das Submenu laden und in das Menu einbinden
        if(menu_container.data('loaded') != true)
        {
            this.load(menu_container, options.url, params, function() {
                menu.select(node, params);                
            });
        }
        else
        {
            /* HTML-Layout:
            <ul parentUL>
                <li>
                    <a onclick="loest den wechsel aus->node"><span>Text</span></a>
                    <ul nextList>...</ul>
                </li>
            </ul>
            */
            
            // Submenu anzeigen            
            var nextList = $(node).next(); // der naechste UL-Tag
            var parentUl = $(node).parents('ul:eq(0)');         
            var parentLeft = (parentUl.is('.fg-menu-content')) ? 0 : parseFloat(menu.toplist.css('left'));
            var nextLeftVal = Math.round(parentLeft - parseFloat(container.width()*2));
            var footer = $('.fg-menu-footer');
        
            // show next menu           
            this.resetChildMenu(parentUl);
            this.checkMenuHeight(nextList);
            nextList.show();
            menu.toplist.stop().animate({ left: nextLeftVal }, options.crossSpeed);
            nextList.addClass('fg-menu-current');


            /* Funktion wechselt das angezeigte Menu eine Ebene zurueck.
             * Steps gibt an, wieviele Menu-Ebenen zurueckgegangen werden soll.
             * 
             */
            var setPrevMenu = function(backlink, level){
                var b = backlink;
                var c = $('.fg-menu-current');
                
                             
                //c.hide();
                menu.resetChildMenu(c);
                menu.checkMenuHeight(new_list);
                new_list.addClass('fg-menu-current').show();
                if (new_list.hasClass('fg-menu-content'))
                {   
                    if(b) b.remove();
                    footer.hide(); 
                };
            };      
        
            // initialize "back" link
            if (options.backLink)
            {
                if (footer.find('a').size() == 0)
                {
                    footer.show();
                    $('<a href="#"><span class="ui-icon ui-icon-triangle-1-w"></span> <span>Back</span></a>')
                        .appendTo(footer)
                        .click(function()
                        {
                            var b = $(this);
                            var prevLeftVal = parseFloat(menu.toplist.css('left')) + container.width()*2;                                              
                            menu.toplist.stop().animate({ left: prevLeftVal },  options.crossSpeed, function()
                            {
                                setPrevMenu(b, 0);
                            });         
                            return false;
                        });
                }
            }
            // or initialize top breadcrumb
            else
            { 
            
                /**
                 *Funktion zum wechseln der Ebenen mit dem BreadCrumb-Menue
                 * `level` Die Ebene auf die gewechselt werden soll
                 * `max_level` Die Maximale Anzahl an Ebenen
                 */
                var switch_level = function(level, max_level)
                {
                    var c = $('.fg-menu-current');
                    var next = c.parents('ul:eq(' + (max_level-level-1) + ')');
                    
                    next.find('ul').each(function() {
                        $(this).hide();
                    });
                    
                    menu.resetChildMenu(c);
                    menu.checkMenuHeight(next);
                    next.addClass('fg-menu-current').show();
                    if (next.hasClass('fg-menu-content')) {   
                        footer.hide(); 
                    };
                };
                
            
                // Falls BreadCrumbs bis jetzt leer (Also erster Ladevorgang) default hinzufuegen
                if(this.breadcrumb.find('li').size() == 1)
                {
                    var max_level = this.breadcrumb.find('li').size()-1;
                    this.breadcrumb
                        .empty()
                        .append(this.firstCrumb)
                        .find('a:eq(0)')
                        .click(function() {
                            menu.resetDrilldownMenu();
                            return false;
                        });
                }
                
                
                $('.fg-menu-current-crumb').removeClass('fg-menu-current-crumb');
                var crumbText = $(node).find('span:eq(0)').text();
                // Crumb erstellen der an die aktuelle Liste angefuegt wird
                var newCrumb = $('<li class="fg-menu-current-crumb"><a href="javascript://" class="fg-menu-crumb"><nobr>'+crumbText+'&nbsp;&#187;</nobr></a></li>'); 
                newCrumb
                    .appendTo(this.breadcrumb)
                    .find('a').click(function()
                    {
                        if ($(this).parent().is('.fg-menu-current-crumb') == false)
                        {
                            var max_level = $(this).parent().parent().find('li').size();
                            var level = $(this).parent().prevAll('li').size();
                            
                            var newLeftVal = -(level * container.width() * 2);
                            menu.toplist.stop().animate({ left: newLeftVal }, options.crossSpeed, function() {
                                switch_level(level, max_level-1);
                            });
                                
                            // make this the current crumb, delete all breadcrumbs after this one, and navigate to the relevant menu
                            $(this).parent().addClass('fg-menu-current-crumb');//.find('span').remove();
                            $(this).parent().nextAll().remove();                                    
                        };
                    
                        return false;
                    });
                        
                    //newCrumb.prev().append(' <span class="ui-icon '+options.nextCrumbLink+'"></span>');
            }
        }
    };
                  
            
            
            
            
                // Short-Cut zum ersten Menu hinzfuegen
               /* if (this.breadcrumb.find('li').size() == 1)
                {
                    this.breadcrumb.empty().append(this.firstCrumb);
                    this.firstCrumb.find('a').click(function()
                    {
                        menu.resetDrilldownMenu();
                        return false;
                    });
                }*/
                
                
            /*    $('.fg-menu-current-crumb').removeClass('fg-menu-current-crumb');
                var crumbText = $(node).find('span:eq(0)').text();
                // Crumb erstellen der an die aktuelle Liste angefuegt wird
                var newCrumb = $('<li class="fg-menu-current-crumb"><a href="javascript://" class="fg-menu-crumb">'+crumbText+'</a></li>'); 
                newCrumb
                    .appendTo(this.breadcrumb)
                    .find('a').click(function()
                    {
                          if ($(this).parent().is('.fg-menu-current-crumb') == false)
                        {
                            var level = $(this).parent().prevAll('li').size();
                            var newLeftVal = -(level * container.width() * 2);
                            menu.toplist.stop().animate({ left: newLeftVal }, options.crossSpeed, function() {
                                setPrevMenu(null, level);
                            });
                                
                            // make this the current crumb, delete all breadcrumbs after this one, and navigate to the relevant menu
                            $(this).parent().addClass('fg-menu-current-crumb').find('span').remove();
                            $(this).parent().nextAll().remove();                                    
                        };
                    
                        return false;
                    });
                        
                newCrumb.prev().append(' <span class="ui-icon '+options.nextCrumbLink+'"></span>');
            };          
        }
        return false;   */        
    
    
    
    /*
     * Laedt die Daten fuer eine Menu-Ebene, wenn sie noch nicht geladen worden sind. Die geladenen Daten
     *
     * `parent_node`
     *      Der Node an den das Menu angehaengt werden soll (LI-Tag)
     * `url`
     *      Die URL von der die Daten gelesen werden
     * `params`
     *      Die Parameter die der URL uebergeben werden. Es muessen Key/Value Paare sein.
     */
    this.load = function(parent_node, url, params, success_function)
    {
        // laden der Daten von der angegeben URL und verarbeiten der daten
        $.getJSON(url, params, function(data)
        {
            /* `data`
             *      JSON-Objekt das die relevanten Daten enthaelt. `data` muss eine Liste von Objekten enthalten.
             *      entry = (leaf=true, text, onclick_action)
             *      entry = (leaf=false, text, url, params)
             */
            var submenu = "<ul>";
        
            // Fuer jeden Eintrag einen Eintrag hinzufuegen
            $(data).each(function(index, elem)
            {
                if(elem.leaf)
                {
                    entry = "<li><a class='leaf' href='" + elem.link + "' onclick='" + elem.onclick + "');'>" + elem.text + "</a></li>";
                }
                else
                {
                    param = $.param(elem.params); // erstellt einen get-string (id=value&id=value&...)
                    entry = "<li><a class='node' name=\"" + param + "\" href=\"#\">";
                    entry += "<span>" + elem.text + "</span><span class=\"ui-icon " + options.nextMenuLink + "\"></span>";
                    entry += "</a></li>";
                }
                    
                submenu += entry;
            });
        
            submenu += "</ul>";
            
            // Submenu an Menu anhaengen und die Menustrukturen erstellen
            // !Submenu erst in Dom-Struktur umwandeln, sonst arbeiten die funktionenen auf zwei verschiedenenStrings !
            submenu = $(submenu);
            $(parent_node).append(submenu);
            menu.menuify(submenu);
            
            // Parent-Node als geladen markieren
            $(parent_node).data('loaded', true);
            
            // Die Erfolgs-Funktion aufrufen falls vorhanden
            if(success_function != null)
                success_function();
        });
    };
    
    
    /*
     * Die Funktion sorgt dafuer, dass dem Submenu alle noetigen Klassen und Javascript-Aktionen hinzugefuegt werden,
     * die zum laufen des IPod-Menus noetig sind.
     * 
     * `submenu`
     *      Das UL-Menu, das eingefuegt wurde.
     */
    this.menuify = function(submenu)
    {        
        var parent = submenu.parent();
        var link = parent.find('a').eq(0);
        
        // Node-Links innerhalb des Submenu initialisieren
        submenu
            .find('a.node')
            .addClass('ui-corner-all fg-menu-indicator')
            .click(function()
            {
                allUIMenus.select(this, $(this).attr('name'));
                return false;
            });
        
        // Leaf-Nodes initialisieren
        submenu
            .find('a.leaf')
            .addClass('ui-corner-all')
        
        // submenu initialisieren
        submenu
            .addClass('ui-corner-all ui-widget-content')
            .css({width: container.width(), left: options.width*2});
        
        //Hover einbauen auf Submenu
        if (options.linkHover)
        {
            var allLinks = submenu.find('li a');
            allLinks.hover(
                function(){
                    var menuitem = $(this);
                    $('.'+options.linkHover).removeClass(options.linkHover).blur().parent().removeAttr('id');
                    $(this).addClass(options.linkHover).focus().parent().attr('id','active-menuitem');
                },
                function(){
                    $(this).removeClass(options.linkHover).blur().parent().removeAttr('id');
                }
            );
        };
        
        if (options.linkHoverSecondary) 
        {
            submenu.find('li').hover(
                function(){
                    $(this).siblings('li').removeClass(options.linkHoverSecondary);
                    if (options.flyOutOnState) { $(this).siblings('li').find('a').removeClass(options.flyOutOnState); }
                    $(this).addClass(options.linkHoverSecondary);
                },
                function(){ $(this).removeClass(options.linkHoverSecondary); }
            );
        };  
    };
};




/* Menu.prototype.setPosition parameters (defaults noted with *):
    referrer = the link (or other element) used to show the overlaid object 
    settings = can override the defaults:
        - posX/Y: where the top left corner of the object should be positioned in relation to its referrer.
                X: left*, center, right
                Y: top, center, bottom*
        - offsetX/Y: the number of pixels to be offset from the x or y position.  Can be a positive or negative number.
        - directionH/V: where the entire menu should appear in relation to its referrer.
                Horizontal: left*, right
                Vertical: up, down*
        - detectH/V: detect the viewport horizontally / vertically
        - linkToFront: copy the menu link and place it on top of the menu (visual effect to make it look like it overlaps the object) */

Menu.prototype.setPosition = function(widget, caller, options) { 
    var el = widget;
    var referrer = caller;
    var dims = {
        refX: referrer.offset().left,
        refY: referrer.offset().top,
        refW: referrer.getTotalWidth(),
        refH: referrer.getTotalHeight()
    };	
    var options = options;
    var xVal, yVal;
    
    var helper = $('<div class="positionHelper"></div>');
    helper.css({ position: 'absolute', left: dims.refX, top: dims.refY, width: dims.refW, height: dims.refH });
    el.wrap(helper);
    
    // get X pos
    switch(options.positionOpts.posX) {
        case 'left': 	xVal = 0; 
            break;				
        case 'center': xVal = dims.refW / 2;
            break;				
        case 'right': xVal = dims.refW;
            break;
    };
    
    // get Y pos
    switch(options.positionOpts.posY) {
        case 'top': 	yVal = 0;
            break;				
        case 'center': yVal = dims.refH / 2;
            break;				
        case 'bottom': yVal = dims.refH;
            break;
    };
    
    // add the offsets (zero by default)
    xVal += options.positionOpts.offsetX;
    yVal += options.positionOpts.offsetY;
    
    // position the object vertically
    if (options.positionOpts.directionV == 'up') {
        el.css({ top: 'auto', bottom: yVal });
        if (options.positionOpts.detectV && !fitVertical(el)) {
            el.css({ bottom: 'auto', top: yVal });
        }
    } 
    else {
        el.css({ bottom: 'auto', top: yVal });
        if (options.positionOpts.detectV && !fitVertical(el)) {
            el.css({ top: 'auto', bottom: yVal });
        }
    };
    
    // and horizontally
    if (options.positionOpts.directionH == 'left') {
        el.css({ left: 'auto', right: xVal });
        if (options.positionOpts.detectH && !fitHorizontal(el)) {
            el.css({ right: 'auto', left: xVal });
        }
    } 
    else {
        el.css({ right: 'auto', left: xVal });
        if (options.positionOpts.detectH && !fitHorizontal(el)) {
            el.css({ left: 'auto', right: xVal });
        }
    };
    
    // if specified, clone the referring element and position it so that it appears on top of the menu
    if (options.positionOpts.linkToFront) {
        referrer.clone().addClass('linkClone').css({
            position: 'absolute', 
            top: 0, 
            right: 'auto', 
            bottom: 'auto', 
            left: 0, 
            width: referrer.width(), 
            height: referrer.height()
        }).insertAfter(el);
    };
};


/* Utilities to sort and find viewport dimensions */

function sortBigToSmall(a, b) { return b - a; };

jQuery.fn.getTotalWidth = function(){
    return $(this).width() + parseInt($(this).css('paddingRight')) + parseInt($(this).css('paddingLeft')) + parseInt($(this).css('borderRightWidth')) + parseInt($(this).css('borderLeftWidth'));
};

jQuery.fn.getTotalHeight = function(){
    return $(this).height() + parseInt($(this).css('paddingTop')) + parseInt($(this).css('paddingBottom')) + parseInt($(this).css('borderTopWidth')) + parseInt($(this).css('borderBottomWidth'));
};

function getScrollTop(){
    return self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
};

function getScrollLeft(){
    return self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
};

function getWindowHeight(){
    var de = document.documentElement;
    return self.innerHeight || (de && de.clientHeight) || document.body.clientHeight;
};

function getWindowWidth(){
    var de = document.documentElement;
    return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
};

/* Utilities to test whether an element will fit in the viewport
    Parameters:
    el = element to position, required
    leftOffset / topOffset = optional parameter if the offset cannot be calculated (i.e., if the object is in the DOM but is set to display: 'none') */
    
function fitHorizontal(el, leftOffset){
    var leftVal = parseInt(leftOffset) || $(el).offset().left;
    return (leftVal + $(el).width() <= getWindowWidth() + getScrollLeft() && leftVal - getScrollLeft() >= 0);
};

function fitVertical(el, topOffset){
    var topVal = parseInt(topOffset) || $(el).offset().top;
    return (topVal + $(el).height() <= getWindowHeight() + getScrollTop() && topVal - getScrollTop() >= 0);
};

/*-------------------------------------------------------------------- 
* javascript method: "pxToEm"
* by:
Scott Jehl (scott@filamentgroup.com) 
Maggie Wachs (maggie@filamentgroup.com)
http://www.filamentgroup.com
*
* Copyright (c) 2008 Filament Group
* Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
*
* Description: Extends the native Number and String objects with pxToEm method. pxToEm converts a pixel value to ems depending on inherited font size.  
* Article: http://www.filamentgroup.com/lab/retaining_scalable_interfaces_with_pixel_to_em_conversion/
* Demo: http://www.filamentgroup.com/examples/pxToEm/	 	
*							
* Options:  	 								
        scope: string or jQuery selector for font-size scoping
        reverse: Boolean, true reverses the conversion to em-px
* Dependencies: jQuery library						  
* Usage Example: myPixelValue.pxToEm(); or myPixelValue.pxToEm({'scope':'#navigation', reverse: true});
*
* Version: 2.0, 08.01.2008 
* Changelog:
*		08.02.2007 initial Version 1.0
*		08.01.2008 - fixed font-size calculation for IE
--------------------------------------------------------------------*/

Number.prototype.pxToEm = String.prototype.pxToEm = function(settings){
    //set defaults
    settings = jQuery.extend({
        scope: 'body',
        reverse: false
    }, settings);
    
    var pxVal = (this == '') ? 0 : parseFloat(this);
    var scopeVal;
    var getWindowWidth = function(){
        var de = document.documentElement;
        return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
    };	
    
    /* When a percentage-based font-size is set on the body, IE returns that percent of the window width as the font-size. 
        For example, if the body font-size is 62.5% and the window width is 1000px, IE will return 625px as the font-size. 	
        When this happens, we calculate the correct body font-size (%) and multiply it by 16 (the standard browser font size) 
        to get an accurate em value. */
                
    if (settings.scope == 'body' && $.browser.msie && (parseFloat($('body').css('font-size')) / getWindowWidth()).toFixed(1) > 0.0) {
        var calcFontSize = function(){		
            return (parseFloat($('body').css('font-size'))/getWindowWidth()).toFixed(3) * 16;
        };
        scopeVal = calcFontSize();
    }
    else { scopeVal = parseFloat(jQuery(settings.scope).css("font-size")); };
            
    var result = (settings.reverse == true) ? (pxVal * scopeVal).toFixed(2) + 'px' : (pxVal / scopeVal).toFixed(2) + 'em';
    return result;
};
