/*
    SiteComponents version:
    6.8.0.1, tag SC_6_8_0_1, created Fri Aug 20 11:18:33 +0200 2010

    Disclaimer
    
    While we make every effort to ensure that this code is fit for its intended
    purpose, we make no guarantees as to its functionality. CoreTrek AS will
    accept no responsibility for the loss of data or any other damage or
    financial loss caused by use of this code.


    Copyright
    
    This programming code is copyright of CoreTrek AS. Permission to run this
    code is given to approved users of CoreTrek's publishing system CorePublish.
    
    This source code may not be copied, modified or otherwise repurposed for use
    by a third party without the written permission of CoreTrek AS.
    
    Contact webmaster@coretrek.com for information.
    
*/

// JSLint validation config
/*jslint laxbreak: true, sub: true, white: false, browser: true,
onevar: false, nomen: false, noindent: true, eqeqeq: false, plusplus: false,
forin: true */
/*global siteComponentsConfig: false, getSiteComponentsConfig: false,
Ajax: false, $$: false, $: false, Element: false, window: false, Class: false,
Effect: false, lightbox: false, PeriodicalExecuter: false, Event: false,
CtCookie: false, cpKeywords: false, CtTooltip: false */

/*

    ============================================================================
    IMPORTANT! This javascript is dependent on Prototype. If you activate
               tooltip, the keyword explanation will have a nicer look.

               Requires CP 6.4 or greater
    ============================================================================

    SiteComponents Keywords

    Replace keywords from the keyword module in given element and all sub elements
    of given element.

    Just include this javascript file to enable.

    Example replacement:

    1: keyword with action: "go to keyword list"
        Before replacement:
            This car looks good
        After replacement :
            This <a class="keyword-replacement keyword-replacement-list keyword-replacement-car"
                    href="http://example.com/keyword-list"
                    target="_self"
                    title="Car is a vehicle with four wheels and an engine.">car</a> looks good

    2: keyword with action: "go to link"
        Before replacement:
            This car looks good
        After replacement :
            This <a class="keyword-replacement keyword-replacement-link keyword-replacement-car"
                    href="http://example.com/car"
                    target="_self"
                    title="Car is a vehicle with four wheels and an engine.">car</a> looks good

    3: keyword with action: "view popup with explanation"
        Before replacement:
            This car looks good
        After replacement :
            This <a class="keyword-replacement keyword-replacement-title keyword-replacement-car"
                    href="#"
                    title="Car is a vehicle with four wheels and an engine."
                    onclick="return false;">car</a> looks good

    SiteComponents Configurations

    component:
        keywords
    parameters:
        array   elements    Array of elements where it's contents keywords should be replaced
        array   skiptags    Array of tags where the keywords should not be replaced
        boolean usetooltip  Whether to activate tooltip function on the links or not
    example:
        var siteComponentsConfig = { 'keywords': { 'elements': ['placeholder-content'],
                                                   'skiptags': ['h1','h2','h3','h4','h5','h6'],
                                                   'usetooltip': true }};
*/

var Keywords = Class.create({
    initialize: function() {
        this.html = '';
        this.replacements = {};
        this.replacementsMacroCounter = 0;
        this.regExpEscapeChars = ['/', '.', '*', '+', '?', '|','(', ')', '[', ']', '{', '}', '\\'];
        this.defaultSkipTags = ['a','textarea','label','legend','option','title','script','style'];
    },

    /**
     * Replace keywords in html
     *
     * You have a parameter that allow you to skip tags. Tags like a, textarea, label and option are skipped by default.
     *
     * @param Object element Replace keywords in elements and all it's sub elements
     * @param Array skipTags Array with tags to skip. Example: ['h1','h2','h3']
     */
    replaceKeywordsInHtml: function(element, skipTags) {
        if(typeof cpKeywords != "undefined" && cpKeywords instanceof Object) {
            this.html = element.innerHTML;
            
            // define the counter used below
            var i;
            
            // 1. Replace skipped tags with a replace macro
            if(skipTags instanceof Array) {
                for(i=0; i<skipTags.length; i++) {
                    this._replaceStringsWithMacrosByPattern(new RegExp('<'+this._escapeRegExpString(skipTags[i])+'.*\\/'+this._escapeRegExpString(skipTags[i])+'>','ig'));
                }
            }

            // 2. Replaced the rest of the tags with a replace macro
            this._replaceStringsWithMacrosByPattern(new RegExp('<[^>]*>','g'));

            // 3. Replace keywords with a macro
            for(i in cpKeywords) {
                switch(cpKeywords[i]['type']) {
                    case 'list':
                    case 'link':
                        this._replaceStringsWithMacrosByPattern(new RegExp('\\b'+i+'\\b','ig'),true,'<a class="keyword-replacement keyword-replacement-'+cpKeywords[i]['type']+' keyword-replacement-'+i.toLowerCase().replace(/[^A-Za-z0-9]/ig,'')+'" href="'+cpKeywords[i]['link']+'" target="'+cpKeywords[i]['target']+'" title="'+cpKeywords[i]['explanation']+'">','</a>');
                        break;
                    case 'title':
                        this._replaceStringsWithMacrosByPattern(new RegExp('\\b'+i+'\\b','ig'),true,'<a class="keyword-replacement keyword-replacement-'+cpKeywords[i]['type']+' keyword-replacement-'+i.toLowerCase().replace(/[^A-Za-z0-9]/ig,'')+'" href="'+cpKeywords[i]['link']+'" title="'+cpKeywords[i]['explanation']+'" onclick="return false;">','</a>');
                        break;
                }
            }

            // 4. Rebuild the text with keywords
            for(i in this.replacements) {
                this.html = this.html.replace(new RegExp(i,'g'),this.replacements[i]);
            }
            element.innerHTML = this.html;

        }
    },

    /**
     * Internal function that replace strings with macros
     *
     * @param RegExp pattern
     * @param boolean useWordBoundary
     * @param string $matchPrefix (Optional) Prefix for the match string
     * @param string $matchSuffix (Optional) Suffix for the match string
     */
    _replaceStringsWithMacrosByPattern: function(pattern,useWordBoundary,matchPrefix,matchSuffix) {
        matchPrefix = matchPrefix === undefined ? '' : matchPrefix;
        matchSuffix = matchSuffix === undefined ? '' : matchSuffix;
        var matches = this.html.match(pattern);
        if(matches instanceof Array) {
            for(var i=0; i<matches.length; i++) {
                var macro = '{::' + this.replacementsMacroCounter++ + '::}';
                this.replacements[macro] = matchPrefix + matches[i] + matchSuffix;
                if(useWordBoundary === true) {
                    this.html = this.html.replace(new RegExp('\\b'+this._escapeRegExpString(matches[i])+'\\b','ig'),macro);
                } else {
                    this.html = this.html.replace(new RegExp(this._escapeRegExpString(matches[i]),'ig'),macro);
                }
            }
        }
    },

    /**
     * Internal function that escapes strings used in a regexp
     *
     * @param string string
     * @return string
     */
    _escapeRegExpString: function(string) {
        return string.replace(new RegExp('(\\' + this.regExpEscapeChars.join('|\\') + ')', 'g'),'\\$1');
    }
});

document.observe('dom:loaded', function(event) {
    var elements = getSiteComponentsConfig('keywords','elements',[]);
    if(elements.length > 0) {
        var keywords = new Keywords();
        for(var i=0; i<elements.length; i++) {
            keywords.replaceKeywordsInHtml($(elements[i]),getSiteComponentsConfig('keywords','skiptags',[]));
        }
        if(getSiteComponentsConfig('keywords','usetooltip',true) &&
           typeof CtTooltip != 'function') {
            new CtTooltip(getSiteComponentsConfig('tooltip','positionby','element'));
        }
    }
});
