/*jslint browser: true, widget: true, white: true, undef: true, nomen : true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, glovar: true */

/*global MONKEY*/
MONKEY = function () {
    var aEvt = window.opera ? false : true;
    var internetExplorer = (window.attachEvent && this.aEvt);
    var newPostsArray = [];
    var yourPostsArray = [];
    var registeredEventListeners = [];
    var positions = { nL: null,
                      nH: null,
                      uL: null,
                      uH: null,
                      lastpos: null };
    var buttons = { u1: null,
                    u2: null,
                    d1: null,
                    d2: null };
    
    var highestPostNumber, highestPostNumberMemory;
    
    return {
        isAEvt: function () {
            return aEvt;
        },
        isIE: function () {
            return internetExplorer;
        },
        getNewPosts: function () {
            return newPostsArray;
        },
        addNewPost: function (newPost) {
            newPostsArray.push(newPost);
            return this;
        },
        getYourPosts: function () {
            return yourPostsArray;
        },
        addYourPost: function (yourPost) {
            yourPostsArray.push(yourPost);
            return this;
        },
        getEventListeners: function () {
            return registeredEventListeners;
        },
        addEventListener: function (listener) {
            registeredEventListeners.push(listener);
        },
        unregisterEventListeners: function (event) {
            var i, rel, target, listener, capture;
            for (i = 0; i < registeredEventListeners.length; i += 1) {
                rel = registeredEventListeners[i];
                target = rel[0];
                event = rel[1];
                listener = rel[2];
                capture = rel[3];
                if (this.isIE()) {
                    target.detachEvent('on' + event, listener);
                    listener = null;
                } else {
                    target.removeEventListener(event, listener, capture);
                }
            }
            newPostsArray = [];
            yourPostsArray = [];
            registeredEventListeners = [];
        },
        getButton: function (button) {
            return buttons[button];
        },
        setButton: function (button, value) {
            buttons[button] = value;
            return this;
        },
        getPosition: function (position) {
            return positions[position];
        },
        setPosition: function (position, value) {
            positions[position] = value;
            return this;
        },
        getHighestPostNumber: function () {
            return highestPostNumber;
        },
        setHighestPostNumber: function (value) {
            highestPostNumber = value;
            return this;
        },
        getHighestPostNumberMemory: function () {
            return highestPostNumberMemory;
        },
        setHighestPostNumberMemory: function (value) {
            highestPostNumberMemory = value;
            return this;
        }
    };
}();

MONKEY.getCookieValue = function (cookie_name, default_value) {
    var dc = document.cookie;
    var prefix = cookie_name + '=';
    var begin = dc.indexOf('; ' + prefix);
    var end;
    
    if (begin === -1) {
        begin = dc.indexOf(prefix);
        if (begin !== 0) {
            return default_value;
        }
    } else {
        begin += 2;
    }
    
    end = dc.indexOf(';', begin);
    if (end === -1) {
        end = dc.length;
    }
    return unescape(dc.substring(begin + prefix.length, end));
};

MONKEY.setCookie = function (name, value, expires, path, domain, secure) {
    var currentCookie = [name, '=', escape(value), 
                         ((expires) ? "; expires=" + expires.toGMTString() : ""), 
                         ((path) ? "; path=" + path : ""),
                         ((domain) ? "; domain=" + domain : ""),
                         ((secure) ? "; secure=" + secure : "")];
    document.cookie = currentCookie.join('');
};

MONKEY.setCookieValue = function (name, value) {
    var now = new Date();
    //31536000000 = 365 * 24 * 60 * 60 * 1000 = 1 year in milliseconds
//    now.setTime(now.getTime() + 31536000000);
    now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000);
    MONKEY.setCookie(name, value, now, "/", false, false);
};

MONKEY.scrollElementIntoView = function (el) {
    if (this.isIE()) { 
        el.scrollIntoView(true); 
        return true; 
    } 
    if (typeof el.offsetLeft !== 'undefined') {
        var cy = 0; 
        while (el) {
            cy += el.offsetTop; 
            el = el.offsetParent; 
        }
        window.scrollTo(0, cy);	
    }	
};

MONKEY.isFunction = function (value) {
    return typeof value === 'function';
};

//Get all elements with a given tag name, or return an empty array
// formerly _gelstn
MONKEY.getElementsByTagName = function (tagName) { 
    if (MONKEY.isFunction(document.getElementsByTagName) || this.isIE()) {
        return document.getElementsByTagName(tagName);
    }
    return [];
};

MONKEY.getChildElementsByName = function (parentNode, tagName) {
    if (MONKEY.isFunction(parentNode.getElementsByTagName)) {
        return parentNode.getElementsByTagName(tagName);
    }
    return [];
};

MONKEY.getPreviousElement = function (node) {
    var previousNode = node.previousSibling;
    while (previousNode.nodeType !== 1) { // A node type of 1 represents an Element
        previousNode = previousNode.previousSibling;
    }
    return previousNode;
};

// Get Element by id.
// formerly _gel
MONKEY.getElementById = function (id) {
    if (MONKEY.isFunction(document.getElementById)) {
        return document.getElementById(id);
    }
    return null;
};

MONKEY.hasClass = function (element, classes) { 
    var f, elementClass, classToTest, regexpString;
    
    for (f = 0; f < classes.length; f += 1) { 
        elementClass = element.className;
        classToTest = classes[f];
        regexpString = '\\b' + classToTest + '\\b'
        if (elementClass.match(regexpString)) { 
            return true; 
        } 
    }
    return false;
};

MONKEY.addClass = function (element, className) {	
    if (!element.className.match('/\\b' + className + '\\b/')) { 
        element.className += ' ' + className;
    }
};

MONKEY.removeClass = function (element, className) {	
    element.className = element.className.replace(new RegExp('\\b' + className + '\\b', 'g'), '');
};

MONKEY.changeClass = function (e, cname) { 
    if (e.className !== name) { 
        if (e.parentNode) { 
            e.parentNode.style.display = 'none'; 
        }
        e.className = cname;	
        if (e.parentNode) { 
            e.parentNode.style.display = ''; 
        }
    }	
};

MONKEY.clientHeight = function () { 
    var myHeight = 0;  
    if (typeof window.innerHeight === 'number') { 
        myHeight = window.innerHeight;   
    } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) { 	
        myHeight = document.documentElement.clientHeight;  
    } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
        myHeight = document.body.clientHeight;  
    } 	
    return myHeight; 	
};

MONKEY.getScrollY = function () {  
    var scrOfY = 0;  
    if (typeof window.pageYOffset  === 'number') { 
        scrOfY = window.pageYOffset; 
    } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) { 
        scrOfY = document.body.scrollTop; 
    } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) { 
        scrOfY = document.documentElement.scrollTop; 
    }  
    return scrOfY; 
};

MONKEY.goTop = function () { 
    if (this.isIE()) {
        document.body.childNodes[0].scrollIntoView(true); 
    } else { 
        window.scroll(0, 0);  
    }    
    return false; //could we return this instead? To aid in function chaining
};

MONKEY.addEvent = function (tget, evt, listener, capture) { 
    this.addEventListener([tget, evt, listener, capture]); 
    if (this.isIE()) { 
        tget.attachEvent('on' + evt, listener); 
    } else { 
        try { 
            tget.addEventListener(evt, listener, capture); 
        } catch (er) {} 
    }
};

MONKEY.capturekey = function (e) {
    var key = e.keyCode;
    var up = window.opera ? 91 : 38;
    var down = window.opera ? 93 : 40;
    
    if (key === down && e.ctrlKey === true && this.getNewPosts().length > 0) {
        MONKEY.navClick(e, this.getButton('d1'));
    }
    if (key === up && e.ctrlKey === true && this.getNewPosts().length > 0) {
        MONKEY.navClick(e, this.getButton('u1'));
    }
    if (key === down && e.altKey === true && this.getYourPosts().length > 0) {
        MONKEY.navClick(e, this.getButton('d2'));
    }
    if (key === up && e.altKey === true && this.getYourPosts().length > 0) {
        MONKEY.navClick(e, this.getButton('u2'));
    }
    //if(key==123 || key==113) togglestyle(); //f12 or f2
};

MONKEY.navClick = function (evt, button) {
    var el = evt; //(_monkey.isIE) ? evt.srcElement : evt.target;
    if (button) { 
        el = button;
    }
    try { 
        el.blur(); 
    } catch (er) {}
    if (el.className.toString().indexOf('disabled') !== -1) {
        return false;
    }

    var id = el.id.toString();	
    var arr = (id === 'PT_u_uplink' || id === 'PT_u_downlink') ? this.getYourPosts() : this.getNewPosts();
    var p = null;
    var pageY = this.getScrollY();
    var cHeight = this.clientHeight();
    var i;
    if (id.indexOf('_uplink') !== -1) { //up
        for (i = arr.length - 1; i >= 0; i -= 1) { 
            if (arr[i].y < pageY) { 
                p = MONKEY.getPreviousElement(arr[i].e); 
//                if (arr[i].e.previousSibling && arr[i].e.previousSibling.className !== '') { 
//                    p = arr[i].e.previousSibling; 
//                    if (arr[i].e.previousSibling.previousSibling && arr[i].e.previousSibling.previousSibling.className !== '') {
//                        p = arr[i].e.previousSibling.previousSibling;
//                    } 
//                } 
                break; 
            } 
        }
    } else {  //down
        for (i = 0; i < arr.length; i += 1) { 
            if (arr[i].y > (pageY + cHeight)) { 
                p = MONKEY.getPreviousElement(arr[i].e);	
//                if (arr[i].e.previousSibling && arr[i].e.previousSibling.className !== '') {	
//                    p = arr[i].e.previousSibling;	
//                    if (arr[i].e.previousSibling.previousSibling && arr[i].e.previousSibling.previousSibling.className !== '') {
//                        p = arr[i].e.previousSibling.previousSibling;
//                    } 
//                }	
                break;	
            } 
        }
    }
    
    if (p) {
        this.scrollElementIntoView(p);
    }
};

MONKEY.checkPosition = function () {
    var pageY = MONKEY.getScrollY();
    var cHeight = MONKEY.clientHeight();
    if (pageY === MONKEY.getPosition('lastpos')) {
        return true;
    }
    MONKEY.setPosition('lastpos', pageY);
    //window.status='y:'+_monkey.positions.lastpos+' low:'+_monkey.positions.nL+' hi:'+_monkey.positions.nH+' > '+(_monkey.positions.lastpos<=_monkey.positions.nL);
    if (MONKEY.getNewPosts().length > 0) {
        if (MONKEY.getPosition('lastpos') <= MONKEY.getPosition('nL')) { 
            MONKEY.changeClass(MONKEY.getButton('u1'), 'PT_LinkDisabled_up');
        } else if (MONKEY.getPosition('lastpos') > MONKEY.getPosition('nL')) {
            MONKEY.changeClass(MONKEY.getButton('u1'), 'PT_Link_up');
        }
        if (MONKEY.getPosition('nH') <= (MONKEY.getPosition('lastpos') + cHeight)) {
            MONKEY.changeClass(MONKEY.getButton('d1'), 'PT_LinkDisabled_down');
        } else if (MONKEY.getPosition('nH') > (MONKEY.getPosition('lastpos') + cHeight)) {
            MONKEY.changeClass(MONKEY.getButton('d1'), 'PT_Link_down');
        }
    }
    if (MONKEY.getYourPosts().length > 0) {
        if (MONKEY.getPosition('lastpos') <= MONKEY.getPosition('uL')) {
            MONKEY.changeClass(MONKEY.getButton('u2'), 'PT_LinkDisabled_up');
        } else if (MONKEY.getPosition('lastpos') > MONKEY.getPosition('uL')) {
            MONKEY.changeClass(MONKEY.getButton('u2'), 'PT_Link_up');
        }
        if (MONKEY.getPosition('uH') <= (MONKEY.getPosition('lastpos') + cHeight)) {
            MONKEY.changeClass(MONKEY.getButton('d2'), 'PT_LinkDisabled_down');
        } else if (MONKEY.getPosition('uH') > (MONKEY.getPosition('lastpos') + cHeight)) {
            MONKEY.changeClass(MONKEY.getButton('d2'), 'PT_Link_down');
        }
    }
};
    
MONKEY.processDiv = function (thisDiv, i) {
    var links = thisDiv.getElementsByTagName('a');
    var postNumber = links[0].getAttribute('href').match(/\d+/)[0];
    var bs = thisDiv.getElementsByTagName('b');
    var uID = thisDiv.getElementsByTagName('div')[2].getElementsByTagName('a')[0].className;
    var cy = 0;
    var newpost;
    if (window.opera) {
        cy = thisDiv.offsetTop;
    } else {
        var el = thisDiv;
        while (el) {
            cy += el.offsetTop;
            el = el.offsetParent;
        }
    }
    var tpad = parseInt(thisDiv.style.paddingLeft, 10) - 5;
    if (tpad < 0) { 
        tpad = 0;
    }
    if (uID === 'owner_link') {
        if (this.getPosition('uL') === null) {
            this.setPosition('uL', cy);
        }
        this.setPosition('uH', cy);
        newpost = {index: i, postid: postNumber, y: cy, e: thisDiv};
        this.addYourPost(newpost);
        //MONKEY.addClass(thisDiv, 'PT_yourPost');
        //thisDiv.style.paddingLeft = tpad + 'px';
    } else if (postNumber > this.getHighestPostNumber()) {
        if (postNumber > this.getHighestPostNumberMemory()) { 
            this.setHighestPostNumberMemory(postNumber); // assign a now higher number
        }
        if (this.getPosition('nL') === null) {
            this.setPosition('nL', cy);
        }
        this.setPosition('nH', cy);
        newpost = {index: i, postid: postNumber, y: cy, e: thisDiv};
        this.addNewPost(newpost);
        this.addClass(thisDiv, 'PT_newPost');
        //thisDiv.style.paddingLeft = tpad + 'px';
    }
};

MONKEY.go = function () {
    //retrieve previous highest post number value, default to 0 if not set
    this.setHighestPostNumber(parseInt(MONKEY.getCookieValue('highestPostNumber', 0), 10));
    this.setHighestPostNumberMemory(this.getHighestPostNumber());
    
    //set the unregisterEventListeners function to be run when the window is closed
    //basically tidy everything up
//    if (MONKEY.isIE()) {
//        window.detachEvent('onunload', this.unregisterEventListeners);
//        MONKEY.unregisterEventListeners = null;
//    } else {
//        window.removeEventListener('unload', this.unregisterEventListeners, false);
//    }
//    if (!window.opera) {
//        this.addEvent(window, 'unload', this.unregisterEventListeners, false);
//    }
    
    this.addEvent(document, 'keydown', this.capturekey, this.aEvt);
    var floatingBox2 = document.createElement('div');
    floatingBox2.id = 'PT_box';
    floatingBox2.className = 'PT_boxTop';
    floatingBox2.innerHTML = 'Loading....';
    //MONKEY.getElementsByTagName('body')[0].appendChild(floatingBox2);
    document.body.appendChild(floatingBox2);

    var fb = "<a href='#' onclick='MONKEY.goTop();return false;' class='PT_Link_up'>Top</a>";
    floatingBox2.innerHTML = fb;
    var thisDiv;
    var divs = MONKEY.getElementsByTagName('div');
    var i;
    //var tc;
    for (i = 0; (thisDiv = divs[i]); i += 1) {
        //tc = thisDiv.className + ' '; 
        if (MONKEY.hasClass(thisDiv, ['post', 'post_odd', 'post_odd_first', 'post_first'])) {
            MONKEY.processDiv(thisDiv, i);
        }
    }
    fb += '| ';
    if (this.getYourPosts().length > 0) {
        fb += "Your posts: <span class='PT_number'>" + this.getYourPosts().length + "</span><a href='#' id='PT_u_uplink' class='PT_LinkDisabled_up' onclick='MONKEY.navClick(this);return false'>Up</a> <a href='#' id='PT_u_downlink' class='PT_Link_down' onclick='MONKEY.navClick(this);return false'>Down</a>";
    }
    if (this.getNewPosts().length > 0 && this.getYourPosts().length > 0) {
        fb += " | ";
    }
    if (this.getNewPosts().length > 0) {
        fb += "New posts: <span class='PT_number'>" + this.getNewPosts().length + "</span><a href='#' id='PT_n_uplink' class='PT_LinkDisabled_up' onclick='MONKEY.navClick(this);return false'>Up</a> <a href='#'  id='PT_n_downlink' class='PT_Link_down' onclick='MONKEY.navClick(this);return false'>Down</a>";
    }
    floatingBox2.innerHTML = fb + "&nbsp;&nbsp;";
    this.setButton('u1', MONKEY.getElementById('PT_n_uplink'));
    this.setButton('d1', MONKEY.getElementById('PT_n_downlink'));
    this.setButton('u2', MONKEY.getElementById('PT_u_uplink'));
    this.setButton('d2', MONKEY.getElementById('PT_u_downlink'));
    if (window.opera) {
        window.onscroll = MONKEY.checkPosition; 	
    } else {
        window.setInterval(MONKEY.checkPosition, 500);
    }
    MONKEY.setCookieValue('highestPostNumber', this.getHighestPostNumberMemory()); // put the new highest value into memory.

};

MONKEY.run = function () {
    // quit if this function has already been called
    if (arguments.callee.done) {
        return;
    }
    arguments.callee.done = true;

    // do stuff
    MONKEY.go();
};





