/*
Dr. Steven Ericsson-Zenith
Institute for Advanced Science & Engineering
Sunnyvale, California, USA
July 21st, 2009

Version 0.2.8.0.m.0.3.0
(Version number reflects YUI Version used)

memeio/structured text project
memeio document client side scripting

This is a Structured Text client side Reader script for the memeio project.

Copyright (c) 2010, Steven Ericsson-Zenith
Institute for Advanced Science & Engineering
All rights reserved. The memeio/structured text project.

*/

/* Abbreviation */
var $ = YAHOO.util.Dom.get

/* the memeio global object */
var memeio = new Object()
memeio.dock = new Array()
memeio.panel = new Array()
memeio.panels = new YAHOO.widget.OverlayManager()

/* memeio client-side methods */
memeio.dismiss = function (close, element) {
    
    cid = YAHOO.util.Dom.generateId(close, 'memeio')
    eid = YAHOO.util.Dom.generateId(element, 'memeio')
    
    /* add handler to the close button associated with things we can dismiss  */
    var fout = new YAHOO.util.Anim(eid, {
        opacity: {
            to: 0
        }
    },
    1, YAHOO.util.Easing.easeIn);
    
    var fin = new YAHOO.util.Anim(eid, {
        opacity: {
            to: 1
        }
    },
    1, YAHOO.util.Easing.easeOut);
    
    YAHOO.util.Event.addListener(cid, 'mousedown',
    function () {
        
        /* we have to reset until the mouse leaves */
        YAHOO.util.Event.removeListener(eid, 'click');
        
        var itimer = setTimeout(function () {
            
            /* add a listener for when the mouse returns */
            YAHOO.util.Event.addListener(eid, 'click',
            function () {
                // bring back
                fin.animate()
            });
        },
        5000) // 5 seconds later
        
        // fade out
        fout.animate()
    });
}

memeio.fade = function (element, seconds) {
    /*
    fade for peripheral items
    may want to add a fade up feature to show faded items periodically
    */
    
    var fout = new YAHOO.util.Anim(element, {
        opacity: {
            to: 0
        }
        /*,
        height: {
        to: 0
        }*/
    },
    1, YAHOO.util.Easing.easeIn);
    
    var fin = new YAHOO.util.Anim(element, {
        opacity: {
            to: 1
        }
        /*,
        height: {
        to: 100, unit: '%'
        }*/
    },
    1, YAHOO.util.Easing.easeOut);
    
    var itimer = setTimeout(function () {
        fout.animate()
    },
    seconds * 1000)
    
    YAHOO.util.Event.addListener(element, 'dblclick',
    function () {
        // Turn on the window scroll event
        YAHOO.util.Event.addListener(window, 'scroll',
        function () {
            clearTimeout(itimer)
            fin.animate()
            itimer = setTimeout(function () {
                fout.animate()
            },
            seconds * 1000)
        });
        YAHOO.util.Event.removeListener(element, 'dblclick');
    });
    
    
    YAHOO.util.Event.addListener(element, 'mouseover',
    function () {
        // bring back
        clearTimeout(itimer)
        fin.animate()
    });
    
    YAHOO.util.Event.addListener(element, 'mouseout',
    function () {
        // fade out
        clearTimeout(itimer)
        itimer = setTimeout(function () {
            fout.animate()
        },
        seconds * 1000)
    });
    
    YAHOO.util.Event.addListener(element, 'mousedown',
    function () {
        YAHOO.util.Event.removeListener(element, 'mouseover');
        
        var itimer = setTimeout(function () {
            /* add a listener for when the mouse returns */
            YAHOO.util.Event.addListener(element, 'mouseover',
            function () {
                // bring back
                clearTimeout(itimer)
                fin.animate()
            });
        },
        5000) // 5 seconds later
        
        
        // fade out
        fout.animate()
    });
}

memeio.effects = function () {
    /*
    in fact want to have fade css class instead of defining the fade items here
    so that the fades can be defined in XSL
    */
    memeio.fade('immediacy', 10)
    memeio.fade('memeio-data', 8)
    memeio.fade('immediacy-data', 4)
    
    /* subliminal "glow": make concepts briefly prominent in text when page opens and when scrolling */
    memeio.gtimer1 = setTimeout(memeio.glow, 2000) // in 2 seconds
    memeio.gtimer2 = setTimeout(memeio.glow, 2300) // in +300ms
    
    
    var timer = setTimeout(function () {
        
        YAHOO.util.Event.addListener(window, 'scroll',
        function () {
            clearTimeout(memeio.gtimer1)
            clearTimeout(memeio.gtimer2)
            // turn off the glow if it is on
            if (! memeio.glowtoggle) {
                memeio.glow()
            }
            
            /* a few seconds after we stop scrolling we will glow concepts */
            memeio.gtimer1 = setTimeout(memeio.glow, 2000) // in 2 seconds
            memeio.gtimer2 = setTimeout(memeio.glow, 2300) // in +300ms
        });
    },
    5000) // after 5 seconds we are going to glow on scroll events
}

memeio.immediacy = function () {
    // in seconds
    var here = new Date(document.lastModified)
    var there = new Date() // the local time
    var age = (there - here) /1000
    var days = Math.floor(age / 86400)
    var dayminutes = Math.floor((age / 86400 - days) * 86400 / 60)
    var hours = Math.floor(dayminutes / 60)
    var minutes = dayminutes < 60? Math.floor((dayminutes / 60) * 60): Math.floor(dayminutes)
    var immediacy = ""
    
    if (days > 0) {
        if (days > 1) {
            immediacy = 'Updated ' + days + ' days ago.'
        } else {
            immediacy = 'This page updated yesterday.'
        }
    } else if (hours > 0 && days != - 1) {
        // days = -1 indicates the client/server clock is out of sync
        if (hours == 1) {
            immediacy = 'Updated an hour ago.'
        } else {
            immediacy = 'Updated ' + hours + ' hours ago.'
        }
    } else if (minutes <= 5 || days == - 1) {
        immediacy = 'This page updated moments ago!'
    } else {
        immediacy = 'Updated just ' + minutes + ' minutes ago.'
    }
    return immediacy
}

/* subliminal glow */
memeio.glowtoggle = true
memeio.glow = function () {
    /* subliminal revelation of concepts */
    var clarification = YAHOO.util.Dom.getElementsByClassName('clarify')
    if (memeio.glowtoggle) {
        // glow clarifications
        if (memeio.toggle) {
            YAHOO.util.Dom.addClass(clarification, 'glow')
        }
    } else {
        // noglow clarifications
        if (memeio.toggle) {
            YAHOO.util.Dom.removeClass(clarification, 'glow')
        }
    }
    memeio.glowtoggle = ! memeio.glowtoggle
}

/* keep track of when we are in clarifications mode */
memeio.toggle = true
memeio.clarify = function () {
    /* reveal clarifications */
    var clarification = YAHOO.util.Dom.getElementsByClassName('clarify')
    var paragraphs = YAHOO.util.Dom.getElementsByClassName('paragraph')
    if (memeio.toggle) {
        // highlight clarifications
        YAHOO.util.Dom.addClass(clarification, 'highlight')
        YAHOO.util.Dom.setStyle(paragraphs, 'display', 'inline')
    } else {
        // nohighlight clarifications
        YAHOO.util.Dom.removeClass(clarification, 'highlight')
        YAHOO.util.Dom.setStyle(paragraphs, 'display', 'none')
    }
    memeio.toggle = ! memeio.toggle
}

// selection methods
memeio.selection = new Object()
memeio.selection.clear = function () {
    
    if (document.selection && document.selection.empty) {
        document.selection.empty();
    } else if (window.getSelection) {
        var s = window.getSelection();
        if (s && s.removeAllRanges)
        s.removeAllRanges();
    }
}

// take the terms to be clarified and decorate them with definitions
memeio.createDecorations = function (clarification, definition, label) {
    
    for (var i = 0;
    i < clarification.length;
    i++) {
        
        // give the clarification a unique id
        term = YAHOO.util.Dom.generateId(clarification[i], 'clarify')
        
        /* mouse events over concepts */
        YAHOO.util.Event.addListener(term, 'mouseover', function () {
            YAHOO.util.Dom.addClass(this, 'highlight')
        },
        $(term), true)
        YAHOO.util.Event.addListener(term, 'mouseout', function () {
            YAHOO.util.Dom.removeClass(this, 'highlight')
        },
        $(term), true)
        
        /* definition panel */
        id = YAHOO.util.Dom.generateId()
        
        memeio.panel[id] = new YAHOO.widget.Panel(id, {
            width: "420px",
            x: 20,
            visible: false,
            draggable: true,
            dragOnly: true,
            close: true,
            strings: {
                close: ''
            },
            underlay: "shadow",
            constraintoviewport: true,
            effect: {
                effect: YAHOO.widget.ContainerEffect.FADE,
                duration: 0.7
            }
        })
        
        memeio.panel[id].setHeader(label)
        memeio.panel[id].setBody(definition[i].innerHTML)
        memeio.panel[id].render(term)
        
        memeio.panels.register(memeio.panel[id])
        
        /* open and close panel events over terms */
        YAHOO.util.Event.addListener(term, 'mousedown', function () {
            // done this way to work around a bug in YUI 2.8.0
            // in which getElementsByTagName("DIV"); fails because of case sensitivity in xhtml pages
            // see discussion at http://yuilibrary.com/forum/viewtopic.php?f=89&t=915
            memeio.panels.bringToTop(this);
            // this .bringToTop()
            this .show()
        },
        memeio.panel[id], true)
        
        YAHOO.util.Event.addListener(term, 'dblclick', function () {
            this .hide()
            memeio.selection.clear()
        },
        memeio.panel[id], true)
    }
}

memeio.concept_map = function () {
    /* open a concept map panel */
    
    id = YAHOO.util.Dom.generateId()
    
    memeio.panel[id] = new YAHOO.widget.Panel(id, {
        width: "940px",
        height: "600px",
        x: "20px",
        visible: false,
        draggable: true,
        dragOnly: true,
        autofillheight: "body",
        close: true,
        strings: {
            close: ''
        },
        constraintoviewport: true
        /*, effect: {
        effect: YAHOO.widget.ContainerEffect.FADE,
        duration: 0.7
        } */
    })
    
    memeio.panel[id].setHeader('Document Concept Map')
    memeio.panel[id].setBody($('concept-map-object').innerHTML)
    memeio.panel[id].render(document.body)
    
    memeio.panels.register(memeio.panel[id])
    
    /* open and close panel */
    /* activate concept map buttons */
    map_buttons = YAHOO.util.Dom.getElementsByClassName('concept-map-button')
    for (var i = 0;
    i < map_buttons.length;
    i++) {
        YAHOO.util.Event.addListener(map_buttons[i], 'mouseover', function () {
            YAHOO.util.Dom.setStyle(YAHOO.util.Dom.getElementsByClassName('concept-map-button'), 'background-color', 'maroon');
        })
        YAHOO.util.Event.addListener(map_buttons[i], 'mouseout', function () {
            YAHOO.util.Dom.setStyle(YAHOO.util.Dom.getElementsByClassName('concept-map-button'), 'background-color', 'pink');
        })
        YAHOO.util.Event.addListener(map_buttons[i], 'click', function () {
            // done this way to work around a bug in YUI 2.8.0
            // in which getElementsByTagName("DIV"); fails because of case sensitivity in xhtml pages
            // see discussion at http://yuilibrary.com/forum/viewtopic.php?f=89&t=915
            memeio.panels.bringToTop(this);
            // this .bringToTop()
            this .show()
        },
        memeio.panel[id], true)
    }
}

// publisher = a global constant defined in the head of the calling document
memeio.initialize = function () {
    
    /* post local immediacy information to the page */
    $('immediacy') .innerHTML = "{ " + memeio.immediacy() + " }"
    /* and update it periodically - we only need to do this if minutes are relevant really */
    setInterval(function () {
        $('immediacy') .innerHTML = "{ " + memeio.immediacy() + " }"
    },
    60000)
    
    /* make the topbar hot */
    YAHOO.util.Event.addListener('topbar', 'click', function () {
        document.location = publisher
    })
    YAHOO.util.Event.addListener('topbar', 'mouseover', function () {
        $("topbar") .className = "topbar light"
    })
    YAHOO.util.Event.addListener('topbar', 'mouseout', function () {
        $("topbar") .className = "topbar dark"
    })
    
    /* activate the button to dismiss the sidebar
    */
    
    /* fire up the sidebar as a panel */
    //memeio.sidebar()
    
    if (YAHOO.util.Dom.inDocument('extras')) {
        memeio.dismiss('sidebar-close', 'extras')
    }
    
    /* activate tabs, if present */
    var tab = YAHOO.util.Dom.getElementsByClassName('tab')
    if (tab.length > 0) {
        /* if this page is tabulated let's activate it */
        var section = YAHOO.util.Dom.getElementsByClassName('section')
        
        for (var i = 0;
        i < tab.length;
        i++) {
            
            /* give the tab a unique id */
            id = YAHOO.util.Dom.generateId(tab[i], 'memeio')
            
            /* add functions to the tabs */
            YAHOO.util.Event.addListener(id, 'mouseover', function () {
                this .className = 'tab highlight'
            },
            $(id), true)
            YAHOO.util.Event.addListener(id, 'mouseout', function () {
                this .className = 'tab nohighlight'
            },
            $(id), true)
            
            /* sections */
            YAHOO.util.Event.addListener(id, 'click', function () {
                
                var section = YAHOO.util.Dom.getElementsByClassName('section')
                
                // sectionOut.animate()
                
                /* close all the tabs (we might want a transition here) */
                for (var i = 0; i < section.length; i++) {
                    YAHOO.util.Dom.setStyle(section[i], 'display', 'none')
                }
                /* and show only this one */
                YAHOO.util.Dom.setStyle(this, 'display', 'inline')
                
                // sectionIn.animate()
                
                var tab = YAHOO.util.Dom.getElementsByClassName('tab')
                for (var i = 0; i < tab.length; i++) {
                    /* take care of the tabs  */
                    if (this === section[i]) {
                        YAHOO.util.Dom.setStyle(tab[i], 'font-size', '20pt')
                        YAHOO.util.Dom.setStyle(tab[i], 'color', 'navy')
                        tab[i] .className = 'tab'
                    } else {
                        YAHOO.util.Dom.setStyle(tab[i], 'font-size', '16pt')
                        YAHOO.util.Dom.setStyle(tab[i], 'color', '#FC0')
                        tab[i] .className = 'tab nohighlight'
                    }
                }
            },
            section[i], true)
        }
        
        /* initialize the first tab view - we are not going to highlight the selected tab */
        YAHOO.util.Dom.setStyle(tab[0], 'font-size', '20pt')
        YAHOO.util.Dom.setStyle(section[0], 'display', 'inline')
    }
    /* end tabs */
    
    /* set up clarifications */
    /* concepts in the document */
    var clarification = YAHOO.util.Dom.getElementsByClassName('clarify')
    var definition = YAHOO.util.Dom.getElementsByClassName('definition')
    
    /* create the panels for each concept */
    memeio.createDecorations(clarification, definition, 'Clarification')
    
    /* abbreviations in the document */
    var abbreviation = YAHOO.util.Dom.getElementsByClassName('abbreviation')
    var specification = YAHOO.util.Dom.getElementsByClassName('specification')
    
    /* create the panels for all the abbreviations in the document */
    memeio.createDecorations(abbreviation, specification, 'Abbreviation')
    
    /* people in the document */
    var person = YAHOO.util.Dom.getElementsByClassName('person')
    var biography = YAHOO.util.Dom.getElementsByClassName('biography')
    
    /* create the panels for all the people in the document */
    memeio.createDecorations(person, biography, 'Person')
    
    /* author's notes in the document */
    var note = YAHOO.util.Dom.getElementsByClassName('annotation')
    var annote = YAHOO.util.Dom.getElementsByClassName('annote')
    
    /* create the panels for all the notes in the document */
    memeio.createDecorations(note, annote, 'Note')
    
    /* references in the document */
    var refer = YAHOO.util.Dom.getElementsByClassName('refer')
    var reference = YAHOO.util.Dom.getElementsByClassName('reference')
    
    /* create the panels for all the references in the document */
    memeio.createDecorations(refer, reference, 'Reference')
    
    /*
    activate buttons that disclose clarifications, after setting up clarifications
    */
    var cbuttons = YAHOO.util.Dom.getElementsByClassName('clarify-button')
    for (var i = 0;
    i < cbuttons.length;
    i++) {
        YAHOO.util.Event.addListener(cbuttons[i], 'mouseover', function () {
            YAHOO.util.Dom.setStyle(YAHOO.util.Dom.getElementsByClassName('clarify-button'), 'background-color', 'maroon');
        })
        YAHOO.util.Event.addListener(cbuttons[i], 'mouseout', function () {
            YAHOO.util.Dom.setStyle(YAHOO.util.Dom.getElementsByClassName('clarify-button'), 'background-color', 'pink');
        })
        YAHOO.util.Event.addListener(cbuttons[i], 'click', memeio.clarify)
    }
    
    /* initialize concept map if present*/
    if (YAHOO.util.Dom.inDocument('concept-map-object')) {
        memeio.concept_map()
    }
    
    /* turn on the page effects */
    memeio.effects()
}

YAHOO.util.Event.onDOMReady(memeio.initialize)