var env=null;
var pedia = null; 

document.onmousemove = mouseMove; 
document.onmouseup = mouseUp;

function interfaceLoad() {
    env = new Environment();
    pedia = new Pedia('loaderContent');
    pedia.setupLinks();
}


function Environment(envId) {
    this.name = 'Pedia Environment';
    this.scrollTimer=null;
    this.scrollerElement=null;
    this.currentScroller=null;
    this.scrollingDirection='';
    this.scrollDragging = 'none';
    this.mousePos = 0;
    this.mouseX = 0;
    this.mouseY = 0;
    this.winPosX = 0;
    this.winPosY = 0;
}

function Pedia(workspaceId) {
    this.name = 'pedia object';
    this.words = new Array();
    this.workspace = document.getElementById(workspaceId);
    this.contentScroller = new VertScroller(this.workspace, 'vert_scroller', true);
    this.wordsContainer = document.getElementById('leftMenu');
    this.wordsScroller = null;
    this.actElement = null;
    this.searchTimer = null;
    this.loader = new ctrl.ContentLoader(this, '/xData/', 'POST', ['object=pedia_article']);
}
Pedia.prototype = {
    ajaxUpdate: function(request) {
        var self = this;
        var xml = request.responseXML.getElementsByTagName('content')[0];
        var html = request.responseText;
        this.showPage(html);
    },
    ajaxLoading: function(request) {
        var self = this;
        cleanupNode(this.workspace);
        placeLoaderLogo(this.workspace);
    },
    handleError: function(request) {
        var self = this;
        cleanupNode(this.workspace);
        this.workspace.innerHTML = "<br/><br/><br/><center>Ошибка загрузки!</center>";
    },
    showPage: function(html) {
        var self = this;
        this.workspace.innerHTML = html;
        this.contentScroller.redraw();
        var links = this.workspace.getElementsByTagName('a');
        for (var i=0; i<links.length; i++) {
            if (links[i].target == '_pedia') {
                links[i].target='';
                var node_id = links[i].href.replace(/.*node_id=(\d+).*/,'$1');
                links[i].href='javascript:elementClick('+node_id+')';
            }
        }
    },
    elementShow: function(id) {
        var self = this;
        var word = document.getElementById('pediaWord'+id);
        if ((word) && (this.actElement != word)) {
            this.loader.sendRequest(['id='+id]);
            if (this.actElement!=null) {
                this.actElement.className = 'item';
            }
            this.actElement = word;
            word.className = 'item_act';
            if ((word.offsetTop>this.wordsContainer.scrollTop+this.wordsContainer.clientHeight)||
                (word.offsetTop+word.offsetHeight<this.wordsContainer.scrollTop)) {
                this.wordsContainer.scrollTop = word.offsetTop;
                this.wordsScroller.moveBar();
            }
        }
    },
    setupLinks: function() {
        var leftCont = document.getElementById('leftMenu');
        var anchors = leftCont.getElementsByTagName('a');
        var id0=LoadedNode;
        var sInput = document.getElementById('searchInput');
        sInput.defaultValue = "";
        sInput.onkeypress = searchKeyPress;
        sInput.value="";
        for (var i=0; i<anchors.length; i++) {
            var r = /.*node_id=(\d+).*/;
            r.exec(anchors[i].href);
            var id = RegExp["$1"];
            anchors[i].href = "javascript:elementClick("+id+")";
            anchors[i].parentNode.id = 'pediaWord'+id;
            this.words.push({id: id, text: anchors[i].innerHTML.toLocaleLowerCase()+" "});
        }
        this.wordsScroller = new VertScroller(leftCont,'vert_scroller', true);
        this.elementShow(id0);
    },
    doSearch: function(searchText) {
        var self = this;
        if (searchText!="") {
            var leftCont = document.getElementById('leftMenu');
            var st = searchText;
            if (st.length<=2) { st = "^"+st; }
            for (var i=0; i<this.words.length; i++) {
                if (this.words[i].text.match(st)!=null) {
                    this.elementShow(this.words[i].id);
                    break;
                }
            }
        }
    },
    startSearchTimer: function() {
        if (this.searchTimer!=null) { window.clearInterval(this.searchTimer); }
        this.searchTimer = window.setInterval(onSearchTimer, 800);
    }
}

function onSearchTimer() {
    window.clearInterval(pedia.searchTimer);
    pedia.searchTimer=null;
    var sInput = document.getElementById('searchInput');
    var searchText = sInput.value.toLocaleLowerCase();
    pedia.doSearch(searchText);
}

function elementClick(id) {
    pedia.elementShow(id);
}
function letterSearch(letter) {
    var searchText = letter.toLocaleLowerCase();
    pedia.doSearch(searchText);
}
function searchKeyPress(event) {
    if (window.event) event = window.event;
    var charCode = event.charCode; 
    var keyCode = event.keyCode;
    if (!charCode) { charCode = keyCode; }
    if (keyCode == 13) {
        searchChange(event);
    }
    if (((charCode>=65)&&(charCode<=90)) ||
       ((charCode>=97)&&(charCode<=122)) ||
       ((charCode>=1040)&&(charCode<=1103)) ||
       (charCode==32)) { 
        pedia.startSearchTimer();
    } else {
        if ((keyCode!=8)&&(keyCode!=37)&&(keyCode!=39)&&(keyCode!=46)&&(keyCode!=32)&&(keyCode!=35)&&(keyCode!=36)) {
            return false;
        }
        if ((keyCode==46) || (keyCode==8)) { 
            pedia.startSearchTimer();
        }
    }
}

/* -------- scroller ----------- */
function VertScroller(element, style, chcSize) {
    this.container = element;
    this.bar = null;
    this.style = style;
    this.container.scrollTop = 0;
    this.scrollerEl = null;
    this.chcSize = chcSize;
    this.scrollerVisible = false;
    if (element.clientHeight<element.scrollHeight) { 
        this.drawScroller();
    }
}

VertScroller.prototype = {
    scrollUpFull: function() {
        this.container.scrollTop = 0;
        this.bar.style.top = '0px';
    },
    scrollDownFull: function() {
        this.container.scrollTop=this.container.scrollHeight-this.container.clientHeight;
        this.bar.style.top = Math.floor(this.container.scrollTop*(this.bar.parentNode.clientHeight/this.container.scrollHeight))+'px';
    },
    drawScroller: function() {
        var element = this.container;
        this.container.scrollTop = 0;
        if (this.chcSize) {
            element.style.width = element.clientWidth-16+'px';
        }
        var parentContainer = element.parentNode;
        var scroller = document.createElement('div');
        this.scrollerEl = scroller;
        scroller.className = this.style;
        scroller.style.top = element.offsetTop+'px';
        scroller.style.left = element.offsetLeft+element.offsetWidth+2+'px';
        scroller.style.height = element.offsetHeight+'px'; 
        var upBtn = document.createElement('div');
        upBtn.className = 'up_btn';
        var downBtn = document.createElement('div');
        downBtn.className = 'down_btn';
        var scrollerBarCont = document.createElement('div');
        scrollerBarCont.className = 'bar_cont';
        scrollerBarCont.style.height = element.offsetHeight-31+'px'
        var scrollerBar = document.createElement('div');
        this.bar = scrollerBar;
        scrollerBar.className = 'bar';
        scrollerBarCont.appendChild(scrollerBar);
        scrollerBar.onmousedown = function(event) { startScrollDrag(scr,'vert',event); }
        var scr = this;
        upBtn.onmousedown = function(event) { startScroll(scr, 'up'); }
        upBtn.onmouseup = function(event) { stopScroll(scr); }
        downBtn.onmousedown = function(event) { startScroll(scr, 'down'); }
        downBtn.onmouseup = function(event) { stopScroll(scr); }
        scroller.appendChild(upBtn);
        scroller.appendChild(downBtn);
        scroller.appendChild(scrollerBarCont);
        parentContainer.appendChild(scroller);
        scrollerBar.style. height = Math.floor(element.clientHeight/element.scrollHeight*scrollerBarCont.clientHeight)+'px';
        this.scrollerVisible = true;
        this.container.onmousewheel = function() { wheelScroll(scr, event.wheelDelta/120); }
    },
    clear: function() {
        this.container.scrollTop = 0;
        if (this.scrollerVisible) {
            cleanupNode(this.scrollerEl);
            this.scrollerEl.parentNode.removeChild(this.scrollerEl);
            if (this.chcSize) {
                this.container.style.width = this.container.clientWidth+16+'px';
            }
            this.container.onmousewheel = null;
            this.scrollerVisible = false;
        }
    },
    redraw: function() {
        this.clear();
        if (this.container.clientHeight<this.container.scrollHeight) { 
            this.drawScroller();
        }
    },
    moveBar: function() {
        this.bar.style.top = Math.floor(this.container.scrollTop*(this.bar.parentNode.clientHeight/this.container.scrollHeight))+'px';;
    }
}

function startScroll(scroller, dir) {
    env.scrollingElement = scroller.container;
    env.currentScroller = scroller;
    env.scrollingDirection = dir;
    env.scrollK=2;
    env.scrollPos=0;
    env.scrollTimer = window.setInterval(doScroll, 10);
}

function stopScroll(scroller) {
    window.clearInterval(env.scrollTimer);
}


function doScroll() {
    if (env.scrollingDirection == 'down') {
        if (env.scrollingElement.scrollTop+env.scrollingElement.clientHeight+env.scrollK<env.scrollingElement.scrollHeight) {
            env.scrollingElement.scrollTop+=env.scrollK;
            env.scrollPos+=env.scrollK;
            var lg = Math.log(env.scrollPos*2)/Math.LN10;
            env.scrollK = (Math.floor(lg)+1)*2;
        } 
        if (env.scrollingElement.scrollTop+env.scrollingElement.clientHeight+env.scrollK>=env.scrollingElement.scrollHeight) {
            env.scrollingElement.scrollTop=env.scrollingElement.scrollHeight-env.scrollingElement.clientHeight;
            window.clearInterval(env.scrollTimer);
        }
        env.currentScroller.bar.style.top = Math.floor(env.scrollingElement.scrollTop*(env.currentScroller.bar.parentNode.clientHeight/env.scrollingElement.scrollHeight))+'px';;
    }
    if (env.scrollingDirection == 'up') {
        if (env.scrollingElement.scrollTop-env.scrollK>0) {
            env.scrollingElement.scrollTop-=env.scrollK;
            env.scrollPos+=env.scrollK;
            var lg = Math.log(env.scrollPos*2)/Math.LN10;
            env.scrollK = (Math.floor(lg)+1)*2;
        } 
        if (env.scrollingElement.scrollTop-env.scrollK<=0) {
            env.scrollingElement.scrollTop=0;
            window.clearInterval(env.scrollTimer);
        }
        env.currentScroller.bar.style.top = Math.floor(env.scrollingElement.scrollTop*(env.currentScroller.bar.parentNode.clientHeight/env.scrollingElement.scrollHeight))+'px';;
    }
}

function startScrollDrag(scroller,vh,event) {
    env.scrollDragging = vh;
    env.currentScroller = scroller;
    env.scrollingElement = scroller.container;
    env.tempFunc = document.onselectstart;
    document.onselectstart = function() { return false; }
    if (vh=='vert') {
        env.scrollPos = scroller.bar.offsetTop;
        try { env.mousePos = event.clientY } catch(err) { env.mousePos = window.event.clientY; }
    }
    if (vh=='hor') {
        env.scrollPos = scroller.bar.offsetLeft;
        try { env.mousePos = event.clientX } catch(err) { env.mousePos = window.event.clientX; }
    }
}
function wheelScroll(scroller, deltaK) { 
    var delta = -deltaK*10;
    var scrollPos = scroller.bar.offsetTop;

    if ((scrollPos+delta>0) && (scrollPos+delta+scroller.bar.offsetHeight<=scroller.bar.parentNode.clientHeight)) {
        scroller.bar.style.top = scrollPos+delta+'px';
        scroller.container.scrollTop = Math.floor((scrollPos+delta)*(scroller.container.scrollHeight/scroller.bar.parentNode.clientHeight));
    }
    if (scrollPos+delta<=0) {
        scroller.bar.style.top = '0px';
        scroller.container.scrollTop = 0;
    }
    if (scrollPos+delta+scroller.bar.offsetHeight>=scroller.bar.parentNode.clientHeight+1) {
        scroller.bar.style.top = scroller.bar.parentNode.clientHeight-scroller.bar.offsetHeight+1+'px';
        scroller.container.scrollTop = scroller.container.scrollHeight-scroller.container.clientHeight;
    }
}
function mouseMove(event) {
    if (env!=null) {
    if (env.scrollDragging=='vert') {
        var newmp;
        try { newmp = event.clientY } catch(err) { newmp = window.event.clientY; }
        var delta = newmp - env.mousePos;
        var scroller = env.currentScroller;
        if ((env.scrollPos+delta>0) && (env.scrollPos+delta+scroller.bar.offsetHeight<=scroller.bar.parentNode.clientHeight)) {
            scroller.bar.style.top = env.scrollPos+delta+'px';
            env.scrollingElement.scrollTop = Math.floor((env.scrollPos+delta)*(env.scrollingElement.scrollHeight/scroller.bar.parentNode.clientHeight));
        }
        if (env.scrollPos+delta<=0) {
            scroller.bar.style.top = '0px';
            env.scrollingElement.scrollTop = 0;
        }
        if (env.scrollPos+delta+scroller.bar.offsetHeight>=scroller.bar.parentNode.clientHeight+1) {
            scroller.bar.style.top = scroller.bar.parentNode.clientHeight-scroller.bar.offsetHeight+1+'px';
            env.scrollingElement.scrollTop = env.scrollingElement.scrollHeight-env.scrollingElement.clientHeight;
        }
    }
    }
}

function mouseUp() {
    if (env!=null) {
        env.scrollDragging = 'none';
        window.clearInterval(env.scrollTimer);
        document.onselectstart = function() { return true; }
    }
}
