/**
 * all.js
 * JavaScript for all pages.
 */

/**
 * LCB Object.
 */
var LCB = {
      _URL: 'http://' + location.host
    , _EXT_LINK_CLASS: 'ext'
    
    /**
     * Checks if link points to external source.
     */
    , isExternalLink: function(href) {
        var exp_for_local = new RegExp('^http://[a-z\.]*' + location.host);
        return(/^http:\/\//.test(href) && !exp_for_local.test(href));
    }
    
    /**
     * Adds class to all external links.
     */
    , markExternalLinks: function(parent_selector) {
        var a_links;

        if(!parent_selector) {
            a_links = $$('a');
        }
        else {
            a_links = $$(parent_selector + ' a');
        }
        
        for (var i = 0; i < a_links.length; ++i) {
            if(LCB.isExternalLink(a_links[i])) {
                a_links[i].addClassName(LCB._EXT_LINK_CLASS);
            }
        }
    } // end markExternalLinks()
};

/**
 * LCB_OVERLAY
 * Provides functions for displaying and hiding a page overlay. To create 
 * an overlay call the getOverlay() function.
 */
var LCB_OVERLAY = {
    _DOCUMENT_OVERLAY_ID: 'doc-overlay'
    , _DOCUMENT_OVERLAY: ''
    , _OPACITY_LOW: 0
    , _OPACITY_HIGH: 0.6
    , _OPACITY_DURATION: 0.6
    , _Z_INDEX_LOW: -1
    , _Z_INDEX_HIGH: 100

    , hide: function() {
        /*
            Original intention is to have overlay fade-out in the same way that it fades-in.
            This requires that the z-index style be applied only AFTER the Opacity animation has completed
            (which is set under _OPACITY_DURATION). However, using Prototype's (v1.6.1) .delay function
            results in an error if browser is IE 7 (and presumably other IE). Instead, just set opacity to 0
            without a fade-out animation.
        */
        //new Effect.Opacity(LCB_OVERLAY._DOCUMENT_OVERLAY_ID, {from: LCB_OVERLAY._OPACITY_HIGH, to: LCB_OVERLAY._OPACITY_LOW, duration: LCB_OVERLAY._OPACITY_DURATION});
        LCB_OVERLAY._DOCUMENT_OVERLAY.setOpacity(LCB_OVERLAY._OVERLAY_LOW);
        LCB_OVERLAY._DOCUMENT_OVERLAY.setStyle({zIndex: LCB_OVERLAY._Z_INDEX_LOW});
    } // end hide: function()
    
    , show: function() {
        new Effect.Opacity(LCB_OVERLAY._DOCUMENT_OVERLAY_ID, {from: LCB_OVERLAY._OPACITY_LOW, to: LCB_OVERLAY._OPACITY_HIGH, duration: LCB_OVERLAY._OPACITY_DURATION});
        LCB_OVERLAY._DOCUMENT_OVERLAY.setStyle({zIndex: LCB_OVERLAY._Z_INDEX_HIGH});
    } // end show: function()
     
    , _initialize: function() {
        if(!$(LCB_OVERLAY._DOCUMENT_OVERLAY_ID)) {
          LCB_OVERLAY._DOCUMENT_OVERLAY = new Element('div', {id: LCB_OVERLAY._DOCUMENT_OVERLAY_ID});
          LCB_OVERLAY._DOCUMENT_OVERLAY.setOpacity(LCB_OVERLAY._OPACITY_LOW);
          LCB_OVERLAY._DOCUMENT_OVERLAY.setStyle({zIndex: LCB_OVERLAY._Z_INDEX_LOW});
          $('ft-wrap').insert({after: LCB_OVERLAY._DOCUMENT_OVERLAY});
        }
    } // end initialize: function()
    
    /**
     * A singleton method to ensure only 1 overlay is ever created.
     */
    , getOverlay: function() {
        LCB_OVERLAY._initialize();
        return LCB_OVERLAY._DOCUMENT_OVERLAY;
    } // end getOverlay: function()
  
};

/**
 * LCB_BUTTONS
 * The LCB buttons appear along the side (secondary content) and are for 
 * linking to pages related to the current one. This JSON Object sets up 
 * the animation of the LCB buttons:
 * 
 *  1. Remove default classname from elements (to stop CSS :hover animation).
 *  2. Add new classname to denote the JS-version.
 *  3. Add onmouseover event handler.
 *  4. Add onmouseout event handler. 
 * 
 * LCB_BUTTONS should be used as a STATIC class i.e. it should NOT be instantiated.
 * The variable 'LCB_BUTTONS' should be used when refering to static variables and 
 * functions. The keyword 'this' should be used for eventhandlers that need 
 * to reference the event target element.
 * 
 * To use: call LCB_BUTTONS.initialize()
 */
var LCB_BUTTONS = {
      _BUTTON_CLASS_DEFAULT: 'lcb-button'
    , _BUTTON_CLASS_JS: 'lcb-button-js'
    
    , revealImg: function(ev) {
        ev.stop();
        
        new Effect.Morph(this.id + '_SPAN', {
          style: 'width: 0'
        , duration: 0.2
        });
    }
    
    , hideImg: function(ev) {
        ev.stop();
        
        new Effect.Morph(this.id + '_SPAN', {
          style: 'width: 32px'
        , duration: 0.2
        //, transition: Effect.Transitions.spring
        });
    }
    
    , initialize: function(){
        var buttons = $$('.' + LCB_BUTTONS._BUTTON_CLASS_DEFAULT);
        
        buttons.each(function(item){
            item.removeClassName(LCB_BUTTONS._BUTTON_CLASS_DEFAULT);
            item.addClassName(LCB_BUTTONS._BUTTON_CLASS_JS);
            item.observe('mouseover', LCB_BUTTONS.revealImg);
            item.observe('mouseout', LCB_BUTTONS.hideImg);
        });
    }
};

/**
 *  LCB_SITE_SEARCH
 *  Initializes the site-wide search functions.
 */
var LCB_SITE_SEARCH = {
      ss: ''
    , SITE_SEARCH_QUERY_ID: 'site-search-query'
    , SITE_SEARCH_RESULTS_ID: 'site-search-results'
    , SITE_SEARCH_SUBMIT_ID: 'site-search-submit'
    , SITE_SEARCH_PAGINATION_CLASS: 'site-search-pagination'
    
    , addPaginationLinks: function() {
        // The cursor object has all things to do with pagination
        var cursor = LCB_SITE_SEARCH.ss.cursor;
        var curPage = cursor.currentPageIndex; // check what page the app is on
        var pagesDiv = new Element('div');
        pagesDiv.addClassName(LCB_SITE_SEARCH.SITE_SEARCH_PAGINATION_CLASS);
        
        for (var i = 0; i < cursor.pages.length; i++) {
            var page = cursor.pages[i];
            
            if (curPage == i) { // if we are on the curPage, then don't make a link
                var label = document.createTextNode(' ' + page.label + ' ');
                pagesDiv.appendChild(label);
            } else {
                // If we aren't on the current page, then we want a link to this page.
                // So we create a link that calls the gotoPage() method on the searcher.
                var link = new Element('a');
                link.href = 'javascript:LCB_SITE_SEARCH.ss.gotoPage('+i+');';
                link.innerHTML = page.label;
                link.style.marginRight = '2px';
                pagesDiv.appendChild(link);
            }
        }

        LCB_SITE_SEARCH.results_div = document.getElementById(LCB_SITE_SEARCH.SITE_SEARCH_RESULTS_ID);
        LCB_SITE_SEARCH.results_div.appendChild(pagesDiv);
    }
    
    , hide: function() {
        // Hide Overlay.
        overlay = LCB_OVERLAY.getOverlay();
        LCB_OVERLAY.hide();
        
        // Hide search results.
         $(LCB_SITE_SEARCH.SITE_SEARCH_RESULTS_ID).setStyle({'display': 'none'});
    }
    
    , initialize: function() {
        LCB_SITE_SEARCH.ss = new google.search.WebSearch();
        LCB_SITE_SEARCH.ss.setSiteRestriction('www.laksamanacollege.edu.bn');
        
        // Add onclick event handler.
        $(LCB_SITE_SEARCH.SITE_SEARCH_SUBMIT_ID).observe('click', function(e) {
            var query = $(LCB_SITE_SEARCH.SITE_SEARCH_QUERY_ID).value;
            LCB_SITE_SEARCH.ss.setSearchCompleteCallback(LCB_SITE_SEARCH.ss, LCB_SITE_SEARCH.searchComplete, null);
            LCB_SITE_SEARCH.ss.execute(query);
            e.stop();
        });
    } // end initialize()
    
    , searchComplete: function() {
        var overlay, result, resultExcerpt, resultExcerptDiv, results, resultTitle, resultTitleDiv, resultUrl, resultUrlDiv, resultWrap;
        
        // Reset the search results div.
        resultsDiv = $(LCB_SITE_SEARCH.SITE_SEARCH_RESULTS_ID);
        resultsDiv.innerHTML = '<h2>Search Results</h2>';
        
        if (LCB_SITE_SEARCH.ss.results && LCB_SITE_SEARCH.ss.results.length > 0) {
            results = LCB_SITE_SEARCH.ss.results;

            // Loop through our results, printing them to the page.
            for (var i = 0; i < results.length; i++) {
                result = results[i];
                resultWrap = new Element('div');
                resultWrap.addClassName('search-result');
                resultTitle = result.titleNoFormatting;
                resultExcerpt = result.content;
                resultUrl = result.url;

                resultTitleDiv = new Element('div');
                resultTitleDiv.innerHTML = '<a href="' + resultUrl + '">' + resultTitle + '</a>';
                resultWrap.appendChild(resultTitleDiv);
                
                resultExcerptDiv = new Element('p');
                resultExcerptDiv.innerHTML = resultExcerpt;
                resultWrap.appendChild(resultExcerptDiv);
                
                resultUrlDiv = new Element('small');
                resultUrlDiv.innerHTML = resultUrl;
                resultWrap.appendChild(resultUrlDiv);

                resultsDiv.appendChild(resultWrap);
            }
            
            // Now add the paging links so the user can see more results.
            LCB_SITE_SEARCH.addPaginationLinks(LCB_SITE_SEARCH.ss);
        } else {
            resultsDiv.innerHTML += '<p>No Results.</p>';
        }
        
        // Display Overlay.
        overlay = LCB_OVERLAY.getOverlay();
        overlay.observe('click', LCB_SITE_SEARCH.hide);
        LCB_OVERLAY.show();
        
        // Display search results.
        resultsDiv.setStyle({'display': 'block'});
    }
};

/**
 *  TEXT_LIGHTBOX
 *  Creates a Lightbox-style effect for text.
 *  
 *  1. Create "close" button for text-lightboxes.
 *  2. Apply CSS class to style text-lightboxes.
 *  3. Movelightboxes off-screen.
 *  4. Have lightboxes slide in when user clicks appropriate lite.
 *  5. Have lightboxes slide out when user clicks close. 
 *
 *  NB/ Firefox 2.0 renders the overlay ON TOP OF the TEXT_LIGHTBOX.
 *  Users cannot select the text in the TEXT_LIGHTBOX nor can they
 *  scroll the viewport.
 */
var TEXT_LIGHTBOX = Class.create({
      id: ''
    , _CLASS: 'text-lightbox'
    , _IMG_FILE_PATH: 'img/windowing-elements/windowing-button-close.png'
    , _BUTTON_CLOSE_CLASS: 'windowing-button close'
    , _WINDOWING_ELEMENTS_WRAP_CLASS: 'windowing-elements-wrap'

    /**
     * <div class="windowingElementsWrap">
     *    <button class="windowing-button close">
     *      <img src="IMG" alt="Close">
     *    </button>
     * </div>
     */
    , createWindowingElements: function() {
        var img = new Element('img', {src: LCB._URL + '/' + this._IMG_FILE_PATH, alt: 'Close'});
        var button = new Element('button', {id: this.id + '_close', className: this._BUTTON_CLOSE_CLASS});
        var div = new Element('div', {className: this._WINDOWING_ELEMENTS_WRAP_CLASS});
        
        button.observe('click', this.hide);
        button.insert({top: img});
        div.insert({top: button});
        
        return div;
    } // end createWindowingElements: function()
    
    , hide: function(ev) {
        var overlay = LCB_OVERLAY.getOverlay();
        
        ev.stop();
        LCB_OVERLAY.hide();
        
        new Effect.Morph(this.id, {
            style: 'left: -660px'
          , duration: 0.8
        });
    } // end hide: function()
    
    , show: function(ev) {
        var overlay = LCB_OVERLAY.getOverlay();
        
        ev.stop();
        
        overlay.observe('click', this.hide.bind(this));
        LCB_OVERLAY.show();

        new Effect.Morph(this.id, {
            style: 'left: 50px'
          , duration: 0.8
        });
    } // end show: function()
    
    , initialize: function(id) {
        this.id = id;
        var lbox = $(id);
        var windowing_elements = this.createWindowingElements();
        
        lbox.insert({top: windowing_elements});
        lbox.addClassName(this._CLASS);
        $(this.id + '_close').observe('click', this.hide.bind(this));
        $(this.id).setStyle({left: '-660px'});
    } // end initialize: function()
});

