var ajaxListener;
var chatReload = "1";
var chatServer = "/ajax/";
var usersNicks = {};
var forceExit = false;
/* ajax lib */
var onloadfuncs = [];
function $(exp) {
    //alert(exp);
    if (typeof exp == 'function') {
        onloadfuncs.push(exp);
    } else if (exp.charAt(0) == '#') {
        return document.getElementById(exp.substring(1));
    } else if (exp.charAt(0) == '.') {
        var elements = document.getElementsByClassName(exp.substring(1));
        //alert(elements.length);
        if (elements.length != 0) return elements[0];
        //alert("not supported");
    }
    return null;
};
function addClass(obj, className) {
    if (obj.className.indexOf(className) < 0) obj.className += " " + className;
};
function removeClass(obj, className) {
    if (obj.className.indexOf(className) >= 0) obj.className = obj.className.replace(className, "");
};
/*Kentaromiura 1.0 version*/
document.getElementsByClassName = function(searchClass,tag,node){
    var p = function(){
        if([].push)return function(a,b){a.push(b);};
        return function(a,b){a[a.length]=b;};
    }();

    node = node || document;
    tag = tag || '*';

    if(document.evaluate){
        var xpr = document.evaluate([".//",tag,"[contains(concat(' ',@class,' '),' ",searchClass," ')]"].join(''),node, null, 0, null),
                t = true,
                els = new Array();
        while(t=xpr.iterateNext()){
            p(els,t);
        }
        return els;
    }


    var els = node.getElementsByTagName(tag),
            pattern = new RegExp(["(^|\\s)",searchClass,"(\\s|$)"].join('')),
            ce = new Array();

    for (var i = 0, max = els.length; i < max; i++) {
        if(pattern.test(els[i].className))
            p(ce,els[i]);
    }
    return ce;
};
function onPageLoad() {
    var exp;
    while((exp = onloadfuncs.pop()) != null) {
        exp();
    }
};
function getAjaxJson(options) {
    var xhr = false;
    if (window.XMLHttpRequest) {
        xhr = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        try {
            xhr = new ActiveXObject("Msxml2.XMLHTTP");
        } catch(e) {
            try {
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            } catch(e) {
                xhr = false;
            }
        }
    }
    if(xhr) {
        xhr.onreadystatechange = function() {
            //parseResponse(xhr, options.success, options.error);
            if (xhr.readyState == 4) {
                if (xhr.status == 200 || xhr.status == 304) {
                    var json;
                    eval("json=" + xhr.responseText);
                    options.success(json);
                    //var data = xhr.responseText;
                    //document.getElementById("datacontainer").innerHTML = data;
                } else {
                    //alert(xhr);
                    /*for (var k in xhr) {
                     if (xhr.hasOwnProperty(k)) {
                     alert(k+"="+xhr[k]);
                     }
                     }*/
                    options.error(xhr.status);
                }
            }
        };

        var i = true;
        var postData = "";
        if (options.type == "GET") {
            if (options.cache == false) {
                options.url += "?_=" + Math.random();
                i = false;
            }
            for (var k in options.data) {
                if (options.data.hasOwnProperty(k)) {
                    options.url += (i?"?":"&");
                    options.url += k + "=" + encodeURIComponent(options.data[k]);
                    if (i) i = false;
                }
            }
        } else {
            //post
            if (options.cache == false) {
                options.url += "?_=" + Math.random();
            }
            for (var k in options.data) {
                if (options.data.hasOwnProperty(k)) {
                    postData += (i?"":"&");
                    postData += k + "=" + encodeURIComponent(options.data[k]);
                    if (i) i = false;
                }
            }
        }

        xhr.open(options.type, options.url, true);
        if (options.type == "POST") {
            xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
            xhr.setRequestHeader("Content-length", postData.length);
            xhr.setRequestHeader("Connection", "close");
        }
        xhr.send(options.type == "GET" ? null : postData);
        //document.getElementById("datacontainer").innerHTML = "...loading...";
        return xhr;
    } else {
        alert("No AJAX Support!");
        return false;
    }
};

/* main functions */
function addHandler(object, event, handler)
{
    if (typeof object.addEventListener != 'undefined')
        object.addEventListener(event, handler, false);
    else if (typeof object.attachEvent != 'undefined')
        object.attachEvent('on' + event, handler);
    else
        throw "Incompatible browser";
};

function removeHandler(object, event, handler)
{
    if (typeof object.removeEventListener != 'undefined')
        object.removeEventListener(event, handler, false);
    else if (typeof object.detachEvent != 'undefined')
        object.detachEvent('on' + event, handler);
    else
        throw "Incompatible browser";
};

//var tmp;
$(function() {
    //setTimeout(chatListen, 300);
    //var z = $("#msg");
    //z.onclick = function() {alert("z");};
    /*z.onkeydown = function(e) {
     z.value="";
     for (var k in e) {
     //if (e.hasOwnProperty(k)) {
     z.value += k+"="+e[k]+";";
     //}
     }
     return false;
     };*/
    /*addHandler(z, "blur", function(e) {
        z.value="z";
        abortAjax();
    });*/

    /*z.onblur = function(e) {
        abortAjax();
        resumeListen();
    };*/
    chatListen();
    //$("#frames").innerHTML += '<script id="frm1" src="/ajax/?_'+Math.random()+'=&act=listen&chat='+chatId+'&reload=1"></script>';
    /*var script = document.createElement('script');
     script.type = "text/javascript";
     script.src = '/ajax/?_'+Math.random()+'=&act=listen&chat='+chatId+'&reload=';
     $("#frames").appendChild(script);*/

});
/*function temp(data) {
 //var z;
 //eval("z="+$("#frm1").contentWindow.document.body.innerHTML);
 //alert(z.messages.length);
 alert("test" + data);
 };*/
//on window close
window.onunload = function () {
    //garbage collector
    //$("*").die();
    //$("*").unbind();
    forceExit = true;
    abortAjax();
};
var chatActive = false;
function abortAjax() {
    //$("#msg").value="ab";
    //chatActive = true;
    forceExit = true;
    if (ajaxListener) {
    //try {
        ajaxListener.abort();
        ajaxListener = null;
    //} catch(e) {}
    }
};
function resumeListen() {
    //chatActive = false;
    forceExit = false;
    chatListen();
}
function chatListen() {
    if (chatActive || forceExit) return false;
    chatActive = true;
    ajaxListener = getAjaxJson({
        type: "GET",
        async: true,
        dataType: "json",
        cache: false,
        url: chatServer,
        data: {
            act: "listen",
            chat: chatId,
            reload: chatReload
        },
        timeout: 10000,
        success: function(msg, textStatus){
            chatActive = false;
            if (chatReload == "1") {
                chatReload = "";
                addClass($("#loading"), "hidden");
                chatUpdateOnlineCount();
            }
            chatOnEvent(msg);
            chatListen();
        },
        error: function(req, textStatus, errorThrown) {
            chatActive = false;
            if (chatReload == "1") {
                chatReload = "";
                //$(".loading").addClass("hidden");
                addClass($("#loading"), "hidden");
                chatUpdateOnlineCount();
            }
            if (!forceExit) setTimeout(chatListen, 3000);
        }
    });
    return false;
};

function chatOnEvent(data) {
    //alert("z");
    var messages = data.messages;
    var users = data.users;
    var events = data.events;
    if (users != undefined) {
        for(var i = 0; i < users.length; i++) {
            var u = users[i];
            if (u.event == "ENTER")
                chatEnterUser(u);
            else if (u.event == "LEAVE")
                chatLeaveUser(u);
        }
    }
    if (messages != undefined) {

        var ms = $(".chatMessages").childNodes;
        var maxMessages = 10;
        if (ms.length >= maxMessages) {
            //$(".chatMessages > div:lt(" + (ms.size() - maxMessages + 1) + ")").remove();
            var i = 0;
            while(i<ms.length - maxMessages + 1) {
                ms[0].parentNode.removeChild(ms[0]);
                i++;
            }
        }
        ms = null;


        var start = 0;
        if (messages.length > 10) start = messages.length - 10;
        var md = $("#chatChannel_main");
        //alert(md);
        //alert(start + " " + messages.length);
        //var i = start;
        //var f = function() {
        for(var i = start; i < messages.length; i++) {

            var m = messages[i];
            //chatAddChannel(m.channel);
            var id = nick2uid(m.channel);

            //var hl = logged ? (m.text.indexOf(userNick) == 0) : false;
            //if (hl) m.text = m.text.substring(userNick.length+1);
            /*var hl = false;
             var s = '<div class="chatMessage'+(hl?' chatMessageToMe':'')+'">';*/
            //var myDate = new Date(m.t);
            //var t = myDate.format("HH:MM:ss");

            //s += '<div class="chatTime">' + t + '</div>';
            /* if (m.from.length != 0) s += '<span class="chatUserFrom"'+(m.nc?' style="color:#'+m.nc+'"':'')+'>'+m.from.replace(/</gi, "&lt;").replace(/>/gi, "&gt;") + ":</span> ";
             if (hl) s += '<span class="chatToUser">'+userNick+':</span>';
             if (m.bold) s += "<strong>";
             if (m.s || m.italic) s += "<em>";
             //
             if (m.tc && m.tc.length != 0) s += '<span style="color:#' + m.tc + '">';
             s += m.text;
             if (m.tc && m.tc.length != 0) s += '</span>';
             if (m.s || m.italic) s += "</em>";
             if (m.bold) s += "</strong>";
             if (id != "main") s += " (приватное сообщение)";
             s += "</div>";
             md.append(s);
             */
            var hl = false;
            var s = ['<div class="chatMessage',(hl?' chatMessageToMe':''),'">'];
            //var myDate = new Date(m.t);
            //var t = myDate.format("HH:MM:ss");

            //s += '<div class="chatTime">' + t + '</div>';
            if (m.from.length != 0) {
                s.push('<span class="chatUserFrom"');
                if (m.nc) {
                    s.push(' style="color:#');
                    s.push(m.nc);
                    s.push('"');
                }
                s.push('>');
                s.push(m.from.replace(/</gi, "&lt;").replace(/>/gi, "&gt;"));
                s.push(":</span> ");
            }
            if (hl) {
                s.push('<span class="chatToUser">');
                s.push(userNick);
                s.push(':</span>');
            }
            if (m.bold) s.push("<strong>");
            if (m.s || m.italic) s.push("<em>");
            //
            if (m.tc && m.tc.length != 0) {
                s.push('<span style="color:#');
                s.push(m.tc);
                s.push('">');
            }
            s.push(m.text);
            if (m.tc && m.tc.length != 0) s.push('</span>');
            if (m.s || m.italic) s.push("</em>");
            if (m.bold) s.push("</strong>");
            if (id != "main") s.push(" (приватное сообщение)");
            s.push("</div>");
            //var tag = document.createTextNode(s.join(''));
            //tag.innerHTML = s.join('');
            //alert(tag);
            //md.appendChild(tag);
            md.innerHTML += s.join('');
            //alert(md.innerHTML);

            /*s = null;
             hl = null;
             m = null;
             id = null;*/

            //alert("t");
            // if (m.channel == chatActiveChannel)
            //     scrollBottom(md);
            // else
            //     changeChatTabNew($("#chat_" + id), true);
            /* i++;
             if (i < messages.length) {
             setTimeout(f, 300);
             } else {
             data = messages = users = events = null;
             //chatListen();
             }*/

            //setTimeout(f, 300);
            //for(var i = start; i < messages.length; i++) {

        }
    }
    /*if (events != undefined) {
     for(var i = 0; i < events.length; i++) {
     var m = events[i];
     //var e = $('<div class="chatEventDiv">' + m.text + '</div>');
     //$(".chatMain").append(e);
     //e.append('<a href="#" class="chatEventClose">закрыть</a>');
     }
     } */
    return false;
};
function chatAction(data, callback) {
    /*if (ajaxListener) {
     alert("active");
     ajaxListener.abort();
     ajaxListener = null;
     }*/
    removeClass($("#loading"), "hidden");
    getAjaxJson({
        type: "POST",
        async: true,
        dataType: "json",
        cache: false,
        url: chatServer,
        data: data,
        timeout: 60000,
        success: function(msg, textStatus){
            addClass($("#loading"), "hidden");
            if (chatOnAction(msg)) {
                if (callback) callback(msg);
            }
        },
        error: function(req, textStatus, errorThrown){
            addClass($("#loading"), "hidden");
            alert("Ошибка связи. Обновите страницу.");
        }
    });
};
function chatOnAction(data) {
    if (data.status == "error") {
        alert(data.msg);
        return false;
    }
    return true;
};
function nick2uid(nick) {
    if (nick == "main") return nick;
    if (usersNicks[nick] == undefined) {
        var count = 0;
        for (var k in usersNicks) {
            if (usersNicks.hasOwnProperty(k)) {
                ++count;
            }
        }
        usersNicks[nick] = count;
    }
    return usersNicks[nick];
};

function chatEnterUser(u) {
    var nick = u.nick;
    var id = nick2uid(nick);
    if (document.getElementById("user_"+id) == undefined) {
        //$(".chatUsers").append('<span id="user_'+id+'">'+nick+'</span>');
        var el = document.createElement("span");
        el.id = "user_" + id;
        el.innerHTML = nick;
        $(".chatUsers").appendChild(el);
    }
    chatUpdateOnlineCount();
};
function chatLeaveUser(u) {
    var nick = u.nick;
    var id = nick2uid(nick);
    var p = $("#user_"+id);
    p.parentNode.removeChild(p);
    chatUpdateOnlineCount();
};
function chatUpdateOnlineCount() {
    $(".chatOnlineCount").innerHTML = $(".chatUsers").childNodes.length;
};
function chatLogin() {
    var n = $("#nick").value;
    if (n.length == 0) return false;
    chatAction({act: "login",
        chat: chatId,
        msg: n,
        pass: $("#pass").value}, function(data) {
        if (data.status == "needpassword") {
            alert("Для этого ника необходимо указать пароль");
        } else if (data.status == "alreadyinchat") {
            alert("Этот пользователь уже в чате");
        } else {
            addClass($(".notlogged"), "hidden");
            removeClass($(".logged"), "hidden");
        }
    });
    return false;
};
function chatLeave() {
    chatAction({act: "leave",
        chat: chatId}, function() {
        addClass($(".logged"), "hidden");
        removeClass($(".notlogged"), "hidden");
    });
    return false;
};
function chatSend() {
    var m = $("#msg");
    var t = m.value;
    if (t.length == 0) return false;
    m.value = "";
    chatAction({
        act: "send",
        chat: chatId,
        channel: "main",
        msg: t
    }, function(data) {
        if (data.status == "notlogged") {
            logged = false;
            addClass($(".logged"), "hidden");
            removeClass($(".notlogged"), "hidden");
        }// else focusSendText();
    });
    return false;
}