var g_test = false; // false

var g_selectedOnce = false;
var g_timerCountDown = null;
var g_timerReveal = null;
var g_timerBackground = null;
var g_countDownYear = 2010;
var g_birthYear = null;
var g_backgroundTone = 100;
var g_result = null;
var g_revealPos = null;
var g_resultElm = null;
var g_referrer = null;
var g_linkOpen = false;
var g_typingSpeedMs = 75; // 80
var g_isPaused = false;
var g_dialogOpen = false;
var g_triedToExit = false;
var g_allowShowMoreLinks = true;

var g_largeDialogWrapMarginTopBottom = 30;
var g_largeDialogWidthwrap = 770;

window.onbeforeunload = confirmExit;

function init() {
    if (g_test) { g_typingSpeedMs = 20; } //
    g_referrer = document.referrer;
}

function confirmExit() {
    g_triedToExit = true;
    if (g_timerReveal != null) return "Page typing too slow? OK, let's show all at once.";
}

function submitYear() {
    g_birthYear = Misc.getFormValue('birthYear');
    g_birthYear = normalizeBirthYear(g_birthYear);
    if ( isBirthYear(g_birthYear) ) {
        if (g_birthYear < 1900 || g_birthYear > 2009 ) {
            alert("Ooops, there's no data available yet for your birthyear...");
        }
        else {
            Misc.hideElm('mainForm');
            Misc.setHtml('countDownBox', g_countDownYear);
            Misc.showElm('countDownBox');
            g_timerCountDown = setInterval('countDown()', 700);
            var speed = g_test ? 10 : 2800;
            setTimeout('startDarkenBackground()', speed);
            loadResult();
        }
    }
    else {
        alert('Please enter your birth year, like 1975...');
    }
    return false;
}

function pauseTyping() {
    if (!g_isPaused && g_timerReveal != null) {
        clearInterval(g_timerReveal);
        g_timerReveal = null;
        g_isPaused = true;
    }
}

function startTyping() {
    if (!g_dialogOpen && g_isPaused && g_timerReveal == null && !g_triedToExit) {
        g_timerReveal = setInterval('revealResult()', g_typingSpeedMs);
        g_isPaused = false;
    }
}

function startRevealResult() {
    Misc.showElm('result');
    g_timerReveal = setInterval('revealResult()', g_typingSpeedMs);
    g_revealPos = 0; // 0, 170, 320, 8180...

    var resultWrapper = document.getElementById('result');
    var pElm = document.createElement('p');
    g_resultElm = resultWrapper.appendChild(pElm);

    Misc.hideElm('countDownBox');
}

function revealResult() {
    var paragraphSplitterChar = '^';
    g_revealPos++;

    var thisChar = g_result.substr(g_revealPos - 1, 1);
    var tagContent = '';
    if (thisChar == '<') {
        while (thisChar != '>') {
            thisChar = g_result.substr(g_revealPos - 1, 1);
            tagContent += thisChar;
            g_revealPos++;
        }

        if ( tagContent.indexOf(' onmousedown=') >= 1 || tagContent.indexOf(' onmouseover=') >= 1 ) {
            g_linkOpen = true;
        }
        else if (tagContent == '</span>') {
            g_linkOpen = false;
        }
    }
    else if (thisChar == paragraphSplitterChar) {
        var resultWrapper = document.getElementById('result');
        var pElm = document.createElement('p');
        g_resultElm = resultWrapper.appendChild(pElm);
        pElm.innerHtml = g_result.substr(0, g_revealPos - 1);
        g_result = g_result.substr(g_revealPos);
        g_revealPos = 0;
    }

    if (g_triedToExit) {
        g_result = Misc.doReplace(g_result, paragraphSplitterChar, '<br /><br />');
        // g_result = Misc.doReplace(g_result, paragraphSplitterChar, '</p><p>') + '</p>';
        clearInterval(g_timerReveal);
        g_timerReveal = null;
        g_revealPos = g_result.length - 1;
    }

    if (g_revealPos > 0) {
        if (g_revealPos <= g_result.length) {
            var resultPart = g_result.substr(0, g_revealPos);
            if (g_linkOpen) { resultPart += '</span>'; }
            g_resultElm.innerHTML = resultPart;
        }
        else {
            clearInterval(g_timerReveal);
            g_timerReveal = null;
        }
    }

    window.scrollBy(0, 15);
}

function startDarkenBackground() {
    var elmLink = document.getElementById('navigationLink');
    elmLink.style.color = '#fff';

    var elmNavigation = document.getElementById('navigation');
    elmNavigation.style.borderColor = '#fff';

    g_timerBackground = setInterval('darkenBackground()', 90);
}

function isBirthYear(v) {
    return v.length == 4 && isNumeric(v);
}

function normalizeBirthYear(v) {
    if (v.length == 2) {
        v = '19' + v;
    }
    return v;
}

function darkenBackground() {
    var speed = g_test ? 100 : 1;
    g_backgroundTone -= speed;
    if (g_backgroundTone < 0) {
        g_backgroundTone = 0;
        clearInterval(g_timerBackground);
        g_timerBackground = null;
        Misc.hideElm('countDown');
        setTimeout('startRevealResult()', 3000);
    }

    var elm = document.getElementById('all');
    elm.style.backgroundColor = 'rgb(' + g_backgroundTone + '%,' + g_backgroundTone + '%,' + g_backgroundTone + '%)'
}

function countDown() {
    if (g_countDownYear > 1985 && g_countDownYear > g_birthYear) {
        g_countDownYear--;
        Misc.setHtml('countDownBox', g_countDownYear);
    }
    else {
        clearInterval(g_timerCountDown);
        g_timerCountDown = null;
        Misc.hideElm('countDownBox');
    }
}

function clickedYearInput() {
    if (!g_selectedOnce) {
        document.mainForm.birthYear.focus();
        document.mainForm.birthYear.select();
        var elm = document.getElementById('birthYear');
        elm.style.color = '#000';
        g_selectedOnce = true;
    }
}

function loadResult() {
    var url = '';
    url = 'data/' + g_birthYear + '.txt';
    // url = 'private/?year=' + g_birthYear;

    if (window.XMLHttpRequest) {
        g_req = new XMLHttpRequest();
    }
    else if (window.ActiveXObject) {
        g_req = new ActiveXObject('Microsoft.XMLHTTP');
    }
    g_req.onreadystatechange = processLoadResult;
    g_req.open('GET', url, true);
    g_req.send(null);
}

function processLoadResult() {
    if (g_req.readyState == 4 && g_req.status == 200) {
        g_result = g_req.responseText;

        var referrer = getNiceReferrer();
        var referrerText = '';
        if (referrer != 'Google' && referrer != 'Yahoo' && referrer != 'Blogoscoped' && referrer != null && referrer != '' && g_birthYear <= 1995) {
            referrerText = 'Or ' + referrer + ', for that matter.';
        }
        g_result = Misc.doReplace(g_result, 'REFERRER', referrerText);
        preloadImagesOfHtmlString(g_result);
    }
}

function preloadImagesOfHtmlString(html) {
    var regex = /([0-9,a-z,\/,\.]+)\.jpg/gi;
    var urls = html.match(regex);
    for (var i = 0; urls && i < urls.length; ++i) {
        Misc.preloadImage(urls[i]);
    }
}

function getNiceReferrer() {
    var referrer = g_referrer;
    referrer = getDomainFromUrl(referrer);
    if (referrer) {
        referrer = Misc.doReplace(referrer, 'www.', '');
        referrer = Misc.doReplace(referrer, '.com', '');
        referrer = referrer.ucFirst();
    }
    return referrer;
}

function getDomainFromUrl(url) {
    var domain = url.match(/:\/\/(.[^/]+)/);
    if (domain) { domain = domain[1]; }
    return domain;
}

function isNumeric(sText) {
    var ValidChars = "0123456789";
    var IsNumber = true;
    var Char;

    for (i = 0; i < sText.length && IsNumber == true; i++) {
        Char = sText.charAt(i);
        if (ValidChars.indexOf(Char) == -1) { IsNumber = false; }
    }
    return IsNumber;
}


/*** Array object ***/

Array.prototype.toUnique = function() {
    var r = new Array();
    o:for (var i = 0, n = this.length; i < n; i++) {
        for (var x = 0, y = r.length; x < y; x++) {
            if (r[x] == this[i] || r[x] + ' ' == this[i] + ' ') {
                continue o;
            }
        }
        r[r.length] = this[i];
    }
    return r;
}

Array.prototype.inArray = function(v) {
    var isIt = false;
    for (var i = 0; i < this.length; i++) {
        if (this[i] == v) {
            isIt = true;
            break;
        }
    }
    return isIt;
}

Array.prototype.removeItem = function(toRemove) {
    // or use splice... http://codepunk.hardwar.org.uk/ajs44.htm
    var r = new Array();
    var max = this.length;
    for (var i = 0; i < max; i++) {
        if (this[i] != toRemove) {
            r[r.length] = this[i];
        }
    }
    return r;
}

/*** String object ***/

String.prototype.ucFirst = function() {
    var f = this.charAt(0).toUpperCase();
    return f + this.substr(1, this.length - 1);
}

String.prototype.toXml = function() {
    return Misc.toXml(this);
}

String.prototype.toName = function(allowUpperCase) {
    return Misc.toName(this, allowUpperCase);
}

String.prototype.toAttribute = function() {
    return Misc.toAttribute(this);
}

String.prototype.trim = function() {
    var s = this;
    if (s) {
        s = s.replace(new RegExp("^[ ]+", "g"), "");
        s = s.replace(new RegExp("[ ]+$", "g"), "");
    }
    return s;
}

String.prototype.cutLength = function(maxLength) {
    if (!maxLength) { maxLength = 20; }
    var value = this;
    var ender = '...';
    if (this.length - ender.length > maxLength) {
        value = this.substr(0, maxLength - ender.length) + ender;
    }
    return value;
}

String.prototype.ucWords = function() {
    if (this) {
        var str = this;
        return (str+'').replace(/^(.)|\s(.)/g, function ( $1 ) { return $1.toUpperCase( ); } );
    }
}

String.prototype.getTextBetween = function(sFrom, sTo) {
    var sPart = '';
    var iFrom = this.indexOf(sFrom);
    var iTo = this.indexOf(sTo, iFrom);
    iFrom += sFrom.length;
    if (iTo > iFrom) { sPart = this.substring(iFrom, iTo); }
    return sPart;
}

String.prototype.replaceAll = function(sFind, sReplace) {
    var s = this;
    var sOld = null;
    while (sOld != s) {
        sOld = s;
        s = s.replace(sFind, sReplace);
    }
    return s;
}

/*** Misc object ***/

function Misc() {
}

Misc.getElm = function(id) {
    return document.getElementById(id);
}

Misc.getCreateElement = function(id) {
    var elm = document.getElementById(id);
    if (!elm) {
        elm = document.createElement('div');
        elm.setAttribute('id', id);
        document.body.appendChild(elm);
    }
    return elm;
}

Misc.toggleElm = function(id) {
    var elm = document.getElementById(id);
    if (elm) {
        if (elm.style.display == 'block') {
            elm.style.display = 'none';
        }
        else {
            elm.style.display = 'block';
        }
    }
}

Misc.isShowing = function(id) {
    var isShowing = false;
    var elm = document.getElementById(id);
    if (elm) { isShowing = elm.style.display == 'block'; }
    return isShowing;
}

Misc.showElm = function(id) {
    var elm = document.getElementById(id);
    if (elm) { elm.style.display = 'block'; }
}

Misc.hideElm = function(id) {
    var elm = document.getElementById(id);
    if (elm) { elm.style.display = 'none'; }
}

Misc.getHtml = function(id) {
    var html;
    var elm = document.getElementById(id);
    if (elm) {
        html = elm.innerHTML;
    }
    else {
        // alert('Element ' + id + ' not found.');
    }
    return html;
}

Misc.setHtml = function(id, html) {
    var elm = document.getElementById(id);
    if (elm) {
        // if (navigator.appName == 'Microsoft Internet Explorer') {
        //     innerHtmlWorkaroundForIExplorer8(elm, html);
        // }
        // else {
            elm.innerHTML = html;
        // }
    }
    else {
        // alert('Element ' + id + ' not found.');
    }
}

Misc.getRandomString = function() {
    var chars = '0123456789abcdefghiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var stringLength = 64;
    var randomString = '';
    for (var i=0; i < stringLength; ++i) {
        var rnum = Math.floor( Math.random() * chars.length );
        randomString += chars.substring(rnum, rnum + 1);
    }
    return randomString;
}

Misc.toXml = function(s) {
    if (s || s == 0) {
        s = s.toString();
        s = s.replace(/&/g, '&amp;');
        s = s.replace(/</g, '&lt;');
        s = s.replace(/>/g, '&gt;');
    }
    else {
        s = '';
    }
    return s;
}

Misc.toAttribute = function(s) {
    if (s) {
        s = s.toString();
        s = Misc.toXml(s);
        s = s.replace(/"/g, '&quot;');
        // todo: s = s.replace(/'/g, '&#145;');
    }
    else {
        s = '';
    }
    return s;
}

Misc.toName = function(s, allowUpperCase) {
    var name = '';
    if (!allowUpperCase) { s = s.toLowerCase(); }
    var allowed = [
            'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
            '0','1','2','3','4','5','6','7','8','9', '_'];
    if (allowUpperCase) {
        var max = allowed.length;
        for (var i = 0; i < max; ++i) {
            var allowedUpper = allowed[i].toUpperCase();
            if (allowedUpper != allowed[i]) {
                allowed[allowed.length] = allowedUpper;
            }
        }
    }
    for (var i = 0; i < s.length; ++i) {
        var letter = s.substring(i, i + 1);
        if ( allowed.inArray(letter) ) { name += letter; }
    }
    return name;
}

Misc.getChars = function(char, numberOfChars) {
    var s = '';
    for (var i = 1; i <= numberOfChars; i++) {
        s += char;
    }
    return s;
}

Misc.forceMinMax = function(v, min, max) {
    if (v < min) {
        v = min;
    }
    else if (v > max) {
        v = max;
    }
    return v;
}

Misc.getRandomInt = function(min, max) {
    return Math.floor( ( (max + 1 - min) * Math.random() ) + min );
}

Misc.getFormValue = function(id) {
    var v = '';
    var elm = document.getElementById(id);
    if (elm) { v = Misc.getElmFormValue(elm); }
    return v;
}

Misc.getElmFormValue = function(elm) {
    var v = '';
    switch (elm.type) {
        case 'checkbox':
            v = elm.checked;
            break;
        default:
            v = elm.value;
    }
    return v;
}

Misc.setFormValue = function(id, v) {
    var elm = document.getElementById(id);
    if (elm) {
        elm.value = v;
    }
}

Misc.preloadImage = function(url) {
    var img =  new Image();
    img.src = url;
}

Misc.pad = function(v) {
    if ( (v+'').length == 1) { v = '0' + v; }
    return v;
}

Misc.focusElm = function(id) {
    var elm = document.getElementById(id);
    if (elm) { elm.focus(); }
}

Misc.setOpacity = function(elm, opacityFloat) {
    elm.style.MozOpacity = opacityFloat;
    elm.style.opacity = opacityFloat;
}

Misc.elmExists = function(id) {
    return !!document.getElementById(id);
}

Misc.escapeRegex = function(s) {
    return s.replace(/([\\\^\$>*+[\]?{}.=!:(|)])/g, '\\$1');
}

Misc.doReplace = function(sAll, sFind, sReplace, caseSensitive) {
    var sFind = Misc.escapeRegex(sFind);
    var regexFind = new RegExp( sFind, (caseSensitive ? 'g' : 'gi') );
    return sAll.replace(regexFind, sReplace);
}

Misc.ucWords = function(s) {
    return (typeof s == 'string') ? s.ucWords() : null;
}

Misc.getParam = function(id) {
    var thisValue = null;
    var hash = parent.location.hash;
    if (hash != '') {
        var params = hash.substring(1);
        if ( params.indexOf('=') >= 0) {
            var nameValues = params.split('&');
            for (var i = 0; i < nameValues.length; ++i) {
                var nameValue = nameValues[i].split('=');
                if (id == nameValue[0]) {
                    thisValue = nameValue[1];
                    break;
                }
            }
        }
    }
    return thisValue;
}

Misc.getGetParam = function(name) {
    // via netlobo.com/url_query_string_javascript.html
    name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
    var regexS = "[\\?&]"+name+"=([^&#]*)";
    var regex = new RegExp( regexS );
    var results = regex.exec( window.location.href );
    if( results == null ) {
        return '';
    }
    else {
        return results[1];
    }
}

function innerHtmlWorkaroundForIExplorer8(el, html) {
    // via Jon Fox
    if (el) {
        var oldEl = (typeof el === "string" ? document.getElementById(el) : el);
        var newEl = document.createElement(oldEl.nodeName);

        newEl.id = oldEl.id;
        newEl.className = oldEl.className;

        newEl.innerHTML = html;
        if(oldEl.parentNode) {
            oldEl.parentNode.replaceChild(newEl, oldEl);
        }
        else {
            oldEl.innerHTML = html;
        }
        return newEl;
    }
}


// -------------

function showMoreLinks(query) {
    // xxx
    if (g_allowShowMoreLinks) {
        g_dialogOpen = true;
        var extraMarginAtBottom = 140;
        pauseTyping();
    
        var query = Misc.doReplace(query, '"', '&quot;');
        var queryEbay = Misc.doReplace(query, ' ', '%2B');
    
        var s = "<strong>More about " + Misc.toXml(query) + ":</strong><br />" +
                "<a href=\"http://www.google.com/cse?cx=001647362868805548177:vfrimzjecpq&amp;ie=UTF-8&amp;sa=Search&amp;q=" + query + "\" target=\"_blank\" rel=\"nofollow\">" +
                "google it</a>&nbsp;or&nbsp;" +
                "<a href=\"http://rover.ebay.com/rover/1/711-53200-19255-0/1?ff3=4&amp;pub=5574865277&amp;toolid=10001&amp;campid=5336547516&amp;customid=&amp;mpre=http%3A%2F%2Fshop.ebay.com%2Fi.html%3FLH_BIN%3D1%26LH_IncludeSIF%3D1%26_nkw%3D" + queryEbay + "\" target=\"_blank\" rel=\"nofollow\">" +
                "buy on eBay</a>";
    
        var height = viewportGetHeight() - g_largeDialogWrapMarginTopBottom;
    
        var wrap = document.getElementById('mainWrapper');
        Misc.setHtml('mainDialog', s);
    
        wrap.style.top = getLargeDialogTop(g_largeDialogWrapMarginTopBottom) + 'px';
        wrap.style.height = ( viewportGetHeight() - g_largeDialogWrapMarginTopBottom - extraMarginAtBottom ) + 'px';
        wrap.style.left = ( viewportGetWidth() / 2 - g_largeDialogWidthwrap / 2) + 'px';
        wrap.style.display = 'block';
    }
}

function hideMoreLinks() {
    g_allowShowMoreLinks = false;
    setTimeout('doAllowShowMoreLinks()', 1500);
    g_dialogOpen = false;
    startTyping();
    Misc.hideElm('mainWrapper');
}

function openLink(url) {
    g_dialogOpen = true;
    var extraMarginAtBottom = 40;
    pauseTyping();

    var height = viewportGetHeight() - g_largeDialogWrapMarginTopBottom;
    var heightIframe = height - 45 - extraMarginAtBottom;

    var wrap = document.getElementById('mainIframeWrapper');
    var iframe = document.getElementById('mainIframe');
    iframe.src = url;
    iframe.style.height = heightIframe + 'px';

    wrap.style.top = getLargeDialogTop(g_largeDialogWrapMarginTopBottom) + 'px';
    wrap.style.height = ( viewportGetHeight() - g_largeDialogWrapMarginTopBottom - extraMarginAtBottom ) + 'px';
    wrap.style.left = ( viewportGetWidth() / 2 - g_largeDialogWidthwrap / 2) + 'px';
    wrap.style.display = 'block';
}

function closeLink() {
    g_dialogOpen = false;
    startTyping();
    Misc.hideElm('mainIframeWrapper');
}

function doAllowShowMoreLinks() {
    g_allowShowMoreLinks = true;
}

function viewportGetHeight() {
    var retval = 0;
    if (window.innerHeight)
        retval = window.innerHeight - 18;
    else if (document.documentElement && document.documentElement.clientHeight) 
        retval = document.documentElement.clientHeight;
    else if (document.body && document.body.clientHeight) 
        retval = document.body.clientHeight;
    return retval;    
}

function getLargeDialogTop(wrapperMarginTopBottom) {
    return Math.round( viewportGetScrollY() + wrapperMarginTopBottom );
}

function viewportGetScrollY() {
    var retval = 0;
    if (typeof window.pageYOffset == "number")
        retval = window.pageYOffset;
    else if (document.documentElement && document.documentElement.scrollTop)
        retval = document.documentElement.scrollTop;
    else if (document.body && document.body.scrollTop) 
        retval = document.body.scrollTop; 
    else if (window.scrollY)
        retval = window.scrollY;
    return retval;
}

function viewportGetWidth() {
    var retval = 0;
    if (window.innerWidth)
        retval = window.innerWidth - 18;
    else if (document.documentElement && document.documentElement.clientWidth) 
        retval = document.documentElement.clientWidth;
    else if (document.body && document.body.clientWidth) 
        retval = document.body.clientWidth;
    return retval;    
}
