﻿//settings
var userSitePrefix = "";
var wwwSitePrefix = "www.";
var rootDomain = "bestpersons.ru";
var rootPath = "http://www.bestpersons.ru/";
var pservicePath = "/pservice/";
var staticPath = "http://st1.bestpersons.ru/";
var filePath = "http://file1.bestpersons.ru/";
var blockAnimationSpeed = 100;
var blockSwapAnimationSpeed = 500;
var blockCloseAnimationSpeed = 500;
//event timeout
var eTimeOut = 10*1000;

//blocks setup
//var bpBlocks = {};
//get window heigth and width
var hh = getWindowHeigth();
var ww = getWindowWidth();
var isAdmin = false;

$(document).ready(function() {
    $("#saveani2_cont").click(function() {if (confirm("Отменить текущую операцию?")) {hidewait_int();}});
    if (logged == 0) {
        var uname = $("input.uname");
        var upass = $("input.upass");
        if (uname.val().length == 0) {
            uname.val("логин").addClass("notInited");
            upass.val("пароль").addClass("notInited");
        }
    }
    bindNotInited("body");
    if (logged != 0) {
        $(".userBarStatus a").click(function() {return updateUserStatus();});
        $(".userBarStatus input").keypress(function(e) {if (e.keyCode==13) updateUserStatus();});
        $(".userBarStatus span").click(function() {
            $(this).hide();
            $(this).next().show();
            $("#userStatus").focus().select();
        });
    }
    if (logged != 0) {
        setTimeout(listenEvents, eTimeOut);
    }
    preloadImages();
});
function bindNotInited(parent) {
    $(".notInited", parent).focus(function() {$(this).removeClass("notInited").unbind("focus");this.value="";});
};
function preloadImages() {
    $.preloadImages(staticPath+"i/button1_hover.png", staticPath+"i/button2_hover.png");
};
function htmlspecialchars(string) { var z =  $('<span>').text(string).html(); z = z.replace(/"/g,"&quot;"); return z; };
function escapequotes(string) { if (string==null || string==undefined) return null; return string.replace(/"/g,"&quot;"); };
/* messenger */
function eMsg(newmsg, lastnick) {
    if (newmsg == 0 && eNewMsg != 0) {
        //$("#newmsg").hide();
        eLastNick = lastnick;
        eNewMsg = newmsg;
        $("#msg").removeClass("newmsg");
        $("#newmsg").parent().parent().attr("href", "http://www.bestpersons.ru/messages/");
    }
    if (newmsg>0 && (eLastNick != lastnick || newmsg != eNewMsg)) {
        eLastNick = lastnick;
        eNewMsg = newmsg;
        //render new & alert
        $("#newmsg").html(eNewMsg);
        $("#newmsg").parent().parent().attr("href", "http://www.bestpersons.ru/messages/"+eLastNick+"/");
        $("#msg").addClass("newmsg");
        //$("#newmsg").css("display","inline");
    }

};

/* event listener */
function listenEvents() {
    $.ajax({
        url: "http://c1.bestpersons.ru/service/events",
        dataType: "script",
        type: "GET",
        data: {},
        cache: false,
        success: function(data){
            setTimeout(listenEvents, eTimeOut);
        },
        error: function() {
            //alert("Error");
            setTimeout(listenEvents, eTimeOut);
        }
    });
};


function getWindowWidth() {
    return self.innerWidth || jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth;
};
function getWindowHeigth() {
    return self.innerHeight || jQuery.boxModel && document.documentElement.clientHeight || document.body.clientHeight;
};

function getPageSize() {

    var xScroll, yScroll;

    if (window.innerHeight && window.scrollMaxY) {
        xScroll = window.innerWidth + window.scrollMaxX;
        yScroll = window.innerHeight + window.scrollMaxY;
    } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
        xScroll = document.body.scrollWidth;
        yScroll = document.body.scrollHeight;
    } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
        xScroll = document.body.offsetWidth;
        yScroll = document.body.offsetHeight;
    }
    var ws = getWindowSize();
    var windowWidth = ws[0], windowHeight = ws[1];
    //var windowWidth = getWindowWidth(), windowHeight = getWindowHeigth();

    /* if (self.innerHeight) {	// all except Explorer
        if(document.documentElement.clientWidth){
            windowWidth = document.documentElement.clientWidth;
        } else {
            windowWidth = self.innerWidth;
        }
        windowHeight = self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
        windowWidth = document.documentElement.clientWidth;
        windowHeight = document.documentElement.clientHeight;
    } else if (document.body) { // other Explorers
        windowWidth = document.body.clientWidth;
        windowHeight = document.body.clientHeight;
    }*/

    // for small pages with total height less then height of the viewport
    if(yScroll < windowHeight){
        pageHeight = windowHeight;
    } else {
        pageHeight = yScroll;
    }

    // for small pages with total width less then width of the viewport
    if(xScroll < windowWidth){
        pageWidth = xScroll;
    } else {
        pageWidth = windowWidth;
    }

    return [pageWidth,pageHeight];
};

function getWindowSize() {
    var windowWidth, windowHeight;

    if (self.innerHeight) {	// all except Explorer
        if(document.documentElement.clientWidth){
            windowWidth = document.documentElement.clientWidth;
        } else {
            windowWidth = self.innerWidth;
        }
        windowHeight = self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
        windowWidth = document.documentElement.clientWidth;
        windowHeight = document.documentElement.clientHeight;
    } else if (document.body) { // other Explorers
        windowWidth = document.body.clientWidth;
        windowHeight = document.body.clientHeight;
    }
    return [windowWidth, windowHeight];
};

//show register popup
/*function registerfirst(v) {
    
    return false;
};*/

var bpOldFieldVal = {};
function checkField(t, m) {
    var val = t.value;
    if (val != "" && bpOldFieldVal[m] != val) {
        bpOldFieldVal[m] = val;
        $.ajax({
            url: pservicePath+"check.jsp",
            dataType: "json",
            type: "POST",
            async: false,
            data: {act: m, fkey: fkey, val: val},
            cache: false,
            success: function(data){
                var cname = $("." + m + "Status");
                if (data.error=='') {
                    //ok
                    cname.removeClass("error").addClass("ok");
                    $(".errorEvent"+m).hide();
                } else {
                    //false
                    cname.removeClass("ok").addClass("error");
                    var ev = $(".errorEvent"+m);
                    if (ev.css("display") != "block") {
                        $("div", ev).html(data.error);
                        ev.css("top",$("."+m+"Wrap").position().top+"px").show();
                    }
                }
            },
            error: function() {
                //
            }
        });
    }
};
function refreshCode() {
    document.getElementById("botcode").src = "http://www.bestpersons.ru/service/ccode?key="+Math.random()+"&bg=F9F9F9";
    return false;
};
function registerhide() {
    $("#singupdiv, #singupdiv2").hide();
    return false;
};
function registerfirst(v) {
    if ($(".bpDemoWrap .registerFormWrap").length!=0) {
        //show existing register form
        showRegisterForm();
    } else {


        /*if (v==1) {
            $("#singupt1").hide();
            $("#singupt2").show();
        } else {
            $("#singupt2").hide();
            $("#singupt1").show();
        }*/
        var s = $("#singupdiv");
        var s2 = $("#singupdiv2");
        s.css("height", getPageSize()[1] + "px");
        s.css("width", getPageSize()[0] + "px");

        s.css("display","block");

        var b = document;
        var hh = self.innerHeight || jQuery.boxModel && document.documentElement.clientHeight || document.body.clientHeight;
        var ww = self.innerWidth || jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth;
        var t = parseInt($(b).scrollTop() + hh/2 - 404/2);
        var l = parseInt($(b).scrollLeft() + ww/2 - 636/2);
        s2.css("top",t+"px");
        s2.css("left",l+"px");
        s2.css("width","636px");

        //s2.css("height","442px");

        s2.css("display","block");
        if (pageTracker) pageTracker._trackPageview('/g1/regclick.html');
    }
    return false;
};
//open chat dialog
function openchat(usernick) {
    if (logged==0) {
        registerfirst();
    } else {
        if (usernick == undefined || usernick=='null') usernick = "";
        else usernick = usernick+'/';
        var newwindow=window.open('http://www.'+rootDomain+'/messages/'+usernick,'chatwindow','height=550,width=600,menubar=no,toolbar=no,location=no,directories=no,resizable=yes');
        if (window.focus) {newwindow.focus();}
    }
    return false;
};

/* block events (block: container div of blocks or single block) */
function bindBlockEvents(block) {
    var b = $(block);
    $(".blockMenuUp", b).attr("title", "выше");
    $(".blockMenuDown", b).attr("title", "ниже");
    //$(".blockMenuClose", b).attr("title", "закрыть");
    $(".blockTitle", b).click(function() {
        var t = $(this);
        var content = $(this).parent().next();
        var blockId = $(this).parent().parent().parent().attr("id").substring(5);
        var skipSlide = false;
        if (content.length == 0) {
            skipSlide = true;
            var o = $(this).offset();
            showwait2("blockload"+blockId, o.left + 200, o.top);
            //create content div
            content = $("<div class=\"blockContent\" style=\"display:none\"></div>");
            $(this).parent().after(content);

            $.ajax({
                url: pservicePath+"blockoperation.jsp",
                dataType: "html",
                type: "post",
                data: {act: "get", blockid: blockId, fkey: fkey},
                cache: false,
                async: true,
                success: function(data){
                    content.html(data);
                    hidewait2("blockload"+blockId);
                    content.slideDown(blockAnimationSpeed);
                    t.removeClass("closed");
                    saveBlockOpenStatus(blockId, true);
                },
                error: function() {
                    hidewait2("blockload"+blockId);
                }
            });
        }
        if (content.css("display") != 'block') {
            //show
            if (!skipSlide) {
                content.slideDown(blockAnimationSpeed);
                t.removeClass("closed");
                saveBlockOpenStatus(blockId, true);
            }
        } else {
            //hide
            content.slideUp(blockAnimationSpeed);
            t.addClass("closed");
            saveBlockOpenStatus(blockId, false);
        }
    });
    if (b.get(0).className == 'block') afterBlockMove(b); else {
        $(".block", b).each(function() {afterBlockMove($(this));});
    }

    $(".blockMenuUp", b).click(function() {moveBlock($(this).parent().parent().parent().parent(), false);});
    $(".blockMenuDown", b).click(function() {moveBlock($(this).parent().parent().parent().parent(), true);});

    //$(".blockMenuClose", b).click(function() {closeBlock($(this).parent().parent().parent().parent());});
};
/* need to call after change block position and on init, block - jq object */
function afterBlockMove(block) {
    if (block.prev(".block").attr("id") == undefined || block.prev(".block").attr("id") == "block1") {
        $(".blockMenuUp", block).addClass("disabled");
    } else $(".blockMenuUp", block).removeClass("disabled");

    if (block.next().next().attr("id") == undefined) {
        $(".blockMenuDown", block).addClass("disabled");
    } else $(".blockMenuDown", block).removeClass("disabled"); 
};
/* move block, block - jquery object */
function moveBlock(block, down) {
    if (!down && $(".blockMenuUp", block).attr("class").indexOf("disabled") >= 0) return;
    if (down && $(".blockMenuDown", block).attr("class").indexOf("disabled") >= 0) return;
    var oldb;
    if (down) {
        oldb = block.next();
        //oldb.after(block);
    } else {
        oldb = block.prev();
        //oldb.before(block);
    }
    //var oldh = block.css("height");
    //block.animate({"height": "0", "padding-top": "0", "padding-bottom": "0"}, blockSwapAnimationSpeed, "linear", function() {
    //block.fadeTo(blockSwapAnimationSpeed, 0);
    block.slideUp(blockSwapAnimationSpeed, function() {
        //block.css("height","0");
        if (down) {
            oldb.after(block);
        } else {
            oldb.before(block);
        }
        //block.fadeIn(blockSwapAnimationSpeed);
        //block.fadeTo(blockSwapAnimationSpeed, 1);
        block.slideDown(blockSwapAnimationSpeed);
        //block.animate({"height": oldh, "padding-top": "18px", "padding-bottom": "18px"}, blockSwapAnimationSpeed);
        //alert(block + "=" + down);
        afterBlockMove(block);
        afterBlockMove(oldb);
        //save status
        $.ajax({
            url: pservicePath+"blockoperation.jsp",
            dataType: "html",
            type: "post",
            data: {act: "updatepos", blockid: block.attr("id").substring(5), blockpos: $(".block").index(block), blockid2: oldb.attr("id").substring(5), blockpos2: $(".block").index(oldb), fkey: fkey},
            cache: false,
            success: function(data){
                //
            },
            error: function() {
                alert("Ошибка");
            }
        });
        //alert('aaaaaaa');

    })

};
/* save open status */
function saveBlockOpenStatus(blockId, opened) {
    $.ajax({
        url: pservicePath+"blockoperation.jsp",
        dataType: "html",
        type: "post",
        data: {act: "updatepened", blockid: blockId, opened: opened?1:0, fkey: fkey},
        cache: false,
        success: function(data){

        },
        error: function() {
            alert("Ошибка");
        }
    });
};
/* block - jq object */
function closeBlock(block) {
    //block.slideUp(blockAnimationSpeed/*, function() {block.remove();}*/);
    var blockId = block.attr("id").substr(5);
    var uBlock = block.prev();
    var dBlock = block.next();
    block.fadeTo(blockCloseAnimationSpeed, 0, function() {
        block.slideUp(blockSwapAnimationSpeed, function() {
            block.remove();
            afterBlockMove(uBlock);
            afterBlockMove(dBlock);
        });
    });
    //save status
    $.ajax({
        url: pservicePath+"blockoperation.jsp",
        dataType: "html",
        type: "post",
        data: {act: "close", blockid: blockId, fkey: fkey},
        cache: false,
        success: function(data){
            $("#block3 .blockContent").html(data);
        },
        error: function() {
            alert("Ошибка");
        }
    });
};
//get block
function getBlock(blockId) {
    $.ajax({
        url: pservicePath+"blockoperation.jsp",
        dataType: "html",
        type: "post",
        data: {act: "get", blockid: blockId, fkey: fkey},
        cache: false,
        success: function(data){
            $("#block"+blockId+" .blockContent").html(data);
        },
        error: function() {
            alert("Ошибка");
        }
    });
    return false;
};

function openBlock(blockId) {
    var b = $("#block"+blockId);
    if (b.get(0) != undefined) {
        closeBlock(b);
    } else {
        $.ajax({
            url: pservicePath+"blockoperation.jsp",
            dataType: "html",
            type: "post",
            data: {act: "open", blockid: blockId, fkey: fkey},
            cache: false,
            success: function(data){
                var title = $("#openblock"+blockId+" span").html();
                $("#block3").before('<div id="block'+blockId+'" style="display:none;" class="block"><div class="blockWrap"><div class="blockHead"><div class="blockMenu"><div class="blockMenuUp"></div><div class="blockMenuDown"></div></div><div class="blockTitle">'+title+'</div></div><div class="blockContent"></div></div></div>');
                $("#block"+blockId+" .blockContent").html(data);
                getBlock(3);
                bindBlockEvents("#block"+blockId);
                afterBlockMove($("#block"+blockId).prev());
                $("#block"+blockId).slideDown(blockCloseAnimationSpeed);
            },
            error: function() {
                alert("Ошибка");
            }
        });
    }
    return false;
};
/* feed messages events */
function bindFeedEvents(parent, opt) {
    $(".feedItemOpen", parent).toggle(function() {
        var messageId = this.id.substring(4);
        var link = this;
        showwait();
        $.ajax({
            type: "get",
            url: pservicePath+"message.jsp",
            data: {id: messageId, uid: $(link).attr("uid")},
            success: function(data){
                $("#smsg"+messageId).hide();
                $("#msg"+messageId).html(data).show();
                $("span", link).html("свернуть");
                $(link).addClass("feedItemClosed");
                hidewait(true);
            },
            error: function() {
                alert("Error");
                hidewait(true);
            }
        });
    },function() {
        var link = this;
        var messageId = this.id.substring(4);
        $("#msg"+messageId).hide();
        $("#smsg"+messageId).show();
        $("span", link).html("развернуть");
        $(link).removeClass("feedItemClosed");
    });
    bindusermenu(parent);
    $(".favadd", parent).click(function() {var pid=this.id.substr(2);addremfav(pid,"add",$(this).attr("uid"))});
    $(".favrem", parent).click(function() {var pid=this.id.substr(2);addremfav(pid,"rem",$(this).attr("uid"))});

    $(".feedItemMoreControl", parent).mouseup(function() {
        var t = $(this);
        var postId = this.id.substring(2);
        var uid = t.attr("uid");
        var hidden = this.className.indexOf("hiddenpost") >= 0;

        var m = $("#postControl");
        if (m.get(0) != undefined) m.remove();
        var dt = '<div id="postControl">';
        if (opt.me || isAdmin) {
            dt += '<a href="#" class="cmdRemovePost" onclick=\"if (!confirm(\'Вы действительно хотите удалить запись?\')) return false;return postOp(\'remove\','+uid+','+postId+')\">удалить</a>';
        } else if (opt.ff) {
            if (hidden) {
                dt += '<a href="#" class="cmdShowPost" onclick=\"return postOp(\'showpost\','+uid+','+postId+')\">восстановить</a>';
            } else {
                dt += '<a href="#" class="cmdHidePost" onclick=\"return postOp(\'hidepost\','+uid+','+postId+')\">скрыть запись</a><br /><a href="#" class="cmdHideBlog" onclick=\"return postOp(\'hideblog\','+uid+','+postId+')\">скрыть блог</a><br /><a href="#" class="cmdHideUser" onclick=\"return postOp(\'hideuser\','+uid+','+postId+')\">скрыть автора</a>';
            }
        } else {
            dt += 'опции отсутствуют';            
        }

        dt += '</div>';
        m = $(dt);
        $("body").append(m);
        m.mousedown(function(e) {
            if (e.stopPropagation)
                e.stopPropagation();

            e.cancelBubble = true;
        });
        
        m.css("left", (t.offset().left+2)+"px");
        m.css("top",(t.offset().top+2)+"px");
        m.show();

    });

    $(".feedTypeMenuPopup", parent).mousedown(function(e) {
        if (e.stopPropagation)
            e.stopPropagation();
        e.cancelBubble = true;
    });
    /*$(".feedTypeMenuPopup a", parent).click(function() {
        var text = $(this).html();
        $(".feedTypeMenu a", parent).html(text);
        $(this).parent().hide();
        return false;
    });*/
    $(".feedTypeMenu a", parent).mouseup(function() {
        var m = $(".feedTypeMenuPopup");
        var t = $(this);              
        m.css("left", (t.offset().left-4)+"px");
        m.css("top",(t.offset().top-4)+"px");
        m.show();

    }).click(function() {return false;});
    //close menu on other click
    $(document).mousedown(function() {$("#postControl,.feedTypeMenuPopup,.groupMenuPopup,.friendsGroupsMenuPopup").hide();});
    $(document).keypress(function(e) {if (e.keyCode==27) {$("#postControl").hide();$(".feedTypeMenuPopup").hide();}});

    if (!opt.doNotImgResize) {
        var sh = 400;
        //var sw = getWindowWidth() - 700;
        var sw = ww - 700;
        if (sw<0) sw = 150;
        $(".feedItemContent img", parent).unbind();
        $(".feedItemContent img", parent).each(function() {
            if (isImageOk(this)) {
                var w = this.width;
                var h = this.height;
                var nw = w;
                var nh = h;
                if (w>sw) {
                    nw = sw;
                    nh = parseInt(sw * h / w);
                }
                if (nh>sh) {
                    nw = parseInt(nw * sh / nh);
                    nh = sh;
                }
                if (nw != w || nh != h) {
                    $(this).unbind().toggle(function() {
                        this.width = w;
                        this.height = h;
                    }, function() {
                        this.width = nw;
                        this.height = nh;
                    }).css("cursor","move");
                    this.height = nh;
                    this.width = nw;
                }
            } else {
                $(this).load(function() {
                    var w = this.width;
                    var h = this.height;
                    var nw = w;
                    var nh = h;
                    if (w>sw) {
                        nw = sw;
                        nh = parseInt(sw * h / w);
                    }
                    if (nh>sh) {
                        nw = parseInt(nw * sh / nh);
                        nh = sh;
                    }
                    if (nw != w || nh != h) {
                        $(this).unbind().toggle(function() {
                            this.width = w;
                            this.height = h;
                        }, function() {
                            this.width = nw;
                            this.height = nh;
                        }).css("cursor","move");
                        this.height = nh;
                        this.width = nw;
                    }
                });
            }
        });
    }
};
//post operations
function postOp(act, uid, postId) {
    showwait();
    $.ajax({
        url: "/service/postedit",
        dataType: "json",
        type: "POST",
        data: {act: act, puserid: uid, pid: postId, fkey: fkey},
        cache: false,
        success: function(data){
            if (data.error!='') {hidewait(true);alert(data.error);} else {
                document.location.reload();
            }
        },
        error: function() {
            alert("Ошибка");
        }
    });
    return false;
};
//check for image load
function isImageOk(img) {
    // During the onload event, IE correctly identifies any images that
    // weren't downloaded as not complete. Others should too. Gecko-based
    // browsers act like NS4 in that they report this incorrectly.
    if (!img.complete) {
        return false;
    }

    // However, they do have two very useful properties: naturalWidth and
    // naturalHeight. These give the true size of the image. If it failed
    // to load, either of these should be zero.
    if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) {
        return false;
    }

    // No other way of checking: assume it's ok.
    return true;
};

/* loading animation */
function showwait() {
    $("body").css("cursor","wait");
    var b = document;
    var t = parseInt($(b).scrollTop() + hh/2 - 85);
    var l = parseInt($(b).scrollLeft() + ww/2 - 85);
    $("#saveani2_cont").css("top",t+"px");
    $("#saveani2_cont").css("left",l+"px");
    var im = $("#saveani2_cont img");
    var oldsrc = im.attr("src");
    if (im.attr("src")!=staticPath+"i/loading2.gif") im.attr("src",staticPath+"i/loading2.gif");
    $("#saveani2, #saveani2_cont").css("display","block");
    return false;
};
function hidewait(notshowok) {
    if (notshowok) {
        hidewait_int();
    } else {
        $("body").css("cursor","default");
        var im = $("#saveani2_cont img");
        var oldsrc = im.attr("src");
        if (im.attr("src")!=staticPath+"i/loading2_ok.gif") im.attr("src",staticPath+"i/loading2_ok.gif");
        setTimeout(function() {hidewait_int();im.attr("src",oldsrc)}, 1000);
    }
    return false;
};
function hidewait_int() {
    $("body").css("cursor","default");
    $("#saveani2, #saveani2_cont").css("display","none");
};

function showwait2(aId, aLeft, aTop) {
    if (document.getElementById(aId) != undefined) return false;    
    var ani = $("<div class=\"loadani\" id=\""+aId+"\"></div>");
    $("body").append(ani);
    ani.css("left", aLeft + "px").css("top", aTop + "px").css("display", "block");
    return true;
};

function hidewait2(aId) {
    $("#" + aId).remove();
    return false;
};

/* user menu */
var umo = false;
var umto, umshow;
var activeuid = 0;
var uidExtractRegexp = /.*\su([0-9]+).*/;
function bindusermenu(r) {
    $(".user", r).hover(function(e) {
        umo = false;
        if (umto) clearTimeout(umto);
        var um = $("#usermenu");
        var th = $(this);
        //
        umshow = setTimeout(function() {
        var lp = th.offset().left - 189;
        if (lp < 0 || th.get(0).className.indexOf("reverse")>=0) {
            lp = th.offset().left + th.width() + 4;
            $(".um_wrap0",um).addClass("um_reverse");
        } else {
            $(".um_wrap0",um).removeClass("um_reverse");
        }
        um.css("left", lp+"px");
        um.css("top", th.offset().top+parseInt(th.height()/2)-61+"px");

        var userid = th.get(0).className.match(uidExtractRegexp)[1];
        if (activeuid==userid) return;
        activeuid = userid;
        $(".um_wrap2",um).html('Загрузка...');
        um.css("display","block");
        $.ajax({
            url: "/service/getusermenu",
            dataType: "json",
            type: "GET",
            data: {act: "get2", userid: userid},
            cache: false,
            success: function(data){
                if (data.nick != undefined) {
                    var link = 'http://'+userSitePrefix+data.nick+"."+rootDomain+"/";
                    var avatar;
                    if (data.feed == '1') {
                        avatar = staticPath + "i/rss40x40.png";
                    } else {
                        avatar = data.avatar!=''?filePath+data.avatar:staticPath+'i/userpic2.gif';
                    }
                    var h = '<div class="um_nick"><div class="feedItemUser'+(data.online=='1'?' online':'')+'"><a target="_blank" title="'+(data.online=='1'?'Online':data.online)+'" href="'+link+'">'+data.anick+'</a></div>' +
                            (data.feed == '0'?'<div class="um_status">'+(data.status!=''?data.status:'&nbsp;')+'</div>':'')+'</div>'+
                            '<div class="um_avatar"><a target="_blank" href="'+link+'"><img src="'+avatar+'" alt=""></a></div>'+
                            (userid != logged ? (data.friend=='1'?'<div class="um_afriend"><a href="#" title="убрать из друзей" onclick="return removefriend('+userid+')">убрать из ленты</a></div>':'<div class="um_add"><a href="#" onclick="return addfriend('+userid+')">добавить в ленту друзей</a></div>'):'')+
                            (data.feed == '0' && userid != logged ?'<div class="um_send"><a href="#" onclick="return openchat(\''+data.nick+'\')">сообщение</a></div>':'') +
                            '<div class="um_feed"><a href="'+link+'feed/">лента</a></div>' +
                            ((data.friend=='1' && userid != logged) ? '<div class="um_group">группа: <a href="#" class="ajaxlink" onclick="return moveToGroup(this,'+userid+','+data.gid+')">'+(data.gid==0?'нет':data.gname)+'</a></div>':'');
                    $(".um_wrap2",um).html(h);
                } else $(".um_wrap2",um).html("Пользователь удален.");
            },
            error: function() {
                um.html("Ошибка");
            }
        });
        },200);
    }, function() {
        if (umshow) clearTimeout(umshow);
        umo = true;
        umto = setTimeout(function() {
            if (umo) {
                var um = $("#usermenu");
                um.hide();
                activeuid = 0;
            }
        },200);
    });
    $("#usermenu").hover(function() {umo=false;if (umto) clearTimeout(umto);}, function() {
        umo=true;
        umto = setTimeout(function() {
            if (umo) {
                var um = $("#usermenu");
                um.hide();
                activeuid = 0;
            }
        },200);
    });
};

var errorTemp = false;

var newEmptyGroupFunc = function(t) {
    if (t.value != "" && t.value != "укажите название" && !errorTemp) {
        errorTemp = true;
        showwait();
        $.ajax({
            url: pservicePath+"friends.jsp",
            dataType: "html",
            type: "POST",
            data: {act: "creategroup", title: t.value, fkey: fkey},
            cache: false,
            success: function(data){
                alert("Группа "+t.value+" создана. Страница будет перезагружена.");
                document.location.reload();
            },
            error: function() {
                hidewait(true);
                alert("Error");
            }
        });
    } else {
        $(t).prev().show();
        $(t).hide();
    }   
};


function moveToGroup(t, uid, gid) {
    var qt = $(t);
    var stext = '<select id=""><option value="0">нет</option>';
    for(ugId in userGroups) {
        stext += '<option value="'+ugId+'"'+(gid==ugId?' selected="selected"':'')+'>'+userGroups[ugId]+'</option>'
    }
    stext += '<option value="-1">создать группу</option></select>';
    var s = $(stext);
    qt.hide();
    qt.after(s);
    s.focus();
    s.blur(function() {$(this).prev().show();$(this).remove();});
    s.change(function() {
        var qs = $(this);
        //alert(qs.val()+" "+qs.text());
        if (qs.val()=="-1") {
            //create group menu
            qs.remove();
            var inputText = $('<input type="text" value="укажите название" class="notInited" />');
            qt.after(inputText);
            bindNotInited(inputText.parent());
            inputText.focus().select();


            var newGroupFunc = function(t) {
                if (t.value != "" && t.value != "укажите название") {
                    showwait();
                    $.ajax({
                        url: pservicePath+"friends.jsp",
                        dataType: "html",
                        type: "POST",
                        data: {act: "creategroupandadd", title: t.value, fkey: fkey, uid: uid},
                        cache: false,
                        success: function(data){
                            //alert("Группа "+t.value+" создана. Страница будет перезагружена.");
                            document.location.reload();
                        },
                        error: function() {
                            errorTemp = true;
                            hidewait(true);
                            alert("Error");
                            errorTemp = false;
                        }
                    });
                } else {
                    $(t).prev().show();
                    $(t).remove();
                }
            };
            /*$(".groupMenuPopup input").keypress(function(e) {
                if (e.keyCode==13) newGroupFunc(this);
            }).blur(function() {if (!errorTemp) newGroupFunc(this)});*/
            inputText.keypress(function(e) {
                if (e.keyCode==13) newGroupFunc(this);
            }).blur(function() {if (!errorTemp) newGroupFunc(this)});
        } else {
            showwait();
            $.ajax({
                url: "/service/getusermenu",
                dataType: "json",
                type: "POST",
                data: {act: "movetogroup", userid: uid, fkey: fkey, gid: qs.val()},
                cache: false,
                success: function(data){
                    qs.prev().html(qs.get(0).options[qs.get(0).selectedIndex].text).show();
                    qs.remove();
                    hidewait();
                },
                error: function() {
                    hidewait(true);
                    alert("Ошибка");
                }
            });
        }
    });
    return false;
};
/* add friend */
function addfriend(userid) {
    showwait();
    $.ajax({
        url: "/service/getusermenu",
        dataType: "json",
        type: "POST",
        data: {act: "add", userid: userid, fkey: fkey},
        cache: false,
        success: function(data){
            if (data.error!='') {
                hidewait(true);
                if (data.error=='login') {registerfirst();} else if (data.error=='already') {} else alert(data.error);
            } else hidewait();
        },
        error: function() {
            hidewait(true);
            alert("Ошибка");
        }
    });
    return false;
};

/* remove friend */
function removefriend(userid) {
    if (!confirm("Вы действительно хотите удалить этого пользователя из своих друзей?")) return false;
    showwait();
    $.ajax({
        url: "/service/getusermenu",
        dataType: "json",
        type: "POST",
        data: {act: "remove", userid: userid, fkey: fkey},
        cache: false,
        success: function(data){
            hidewait();            
        },
        error: function() {
            hidewait(true);
            alert("Ошибка");
        }
    });
    return false;
};

/* add or remove favorite item */
function addremfav(postid, act, postuserid) {
    if (logged==0) {
        registerfirst();
    } else {
        $.ajax({
            url: "/service/postedit",
            dataType: "json",
            type: "POST",
            data: {act: act=='add'?'addfav':'remfav', pid: postid, puserid: postuserid, fkey: fkey},
            cache: false,
            success: function(data){
                if (data.error!='') {alert(data.error);} else {
                    var fc = $("#fc"+postid);
                    fc.unbind();
                    if (act=='add') {
                        fc.removeClass("favadd");
                        fc.addClass("favrem");
                        fc.click(function() {addremfav(postid,"rem",postuserid)});
                    } else {
                        fc.removeClass("favrem");
                        fc.addClass("favadd");
                        fc.click(function() {addremfav(postid,"add",postuserid)});
                    }

                }
            },
            error: function() {
                //hidewait(true);
                alert("Ошибка");
            }
        });
    }
    return false;
};

/* votes */
function doVote(postId, userId, sign) {
    $.ajax({
        type: "post",
        url: "/service/vote",
        data: {sign: sign, post_id: postId, user_id: userId, fkey: fkey},
        dataType: "json",
        cache: false,
        success: function(data){
            if (data.error=='registerfirst') {
                registerfirst();
            } else if (data.error=='') {
                var obj = $("#voteResult" + postId);
                obj.text(data.value);
                obj.removeClass("voteGreen").removeClass("voteRed");
                if (data.value>0) obj.addClass("voteGreen"); else obj.addClass("voteRed");
            } else alert(data.error);
        },
        error: function() {
            $("#voteResult" + postId).css({color: "red"});
        }
    });
};

/* save user status */
function updateUserStatus() {
    var status = $("#userStatus").val();    
    showwait();
    $.ajax({
        url: "/service/useredit",
        dataType: "json",
        type: "POST",
        data: {act: "setstatus", val: status, fkey: fkey},
        cache: false,
        success: function(data){
            if (data.error=='') {
                $("#userStatusForm").hide();
                $(".currentstatus"+logged).html(data.val).show();
                hidewait();
            } else {
                hidewait(true);
                alert(data.error);
            }
        },
        error: function() {
            hidewait(true);
            alert("Error");

        }
    });
    return false;
};

var activeFriendsGroupId;
/* bind events to friends block */
function bindfriendsmenu(parent) {
    $("#friendsSearch").keyup(function() {
            if (this.value.length==0) {$("#friendsSearchResult").hide();$("#friendsContent").show();return;}
            $.ajax({
                url: pservicePath+"friends.jsp",
                dataType: "html",
                type: "get",
                data: {act: "search", text: this.value, fkey: fkey},
                cache: false,
                success: function(data){
                    $("#friendsContent").hide();
                    $("#friendsSearchResult").unbind("*");
                    $("#friendsSearchResult").html(data).show();
                    bindusermenu("#friendsSearchResult");
                },
                error: function() {
                    alert("Error");
                }
            });
        });
    $(".friendsGroupsMenuPopupItem", parent).hover(function() {$("img", this).css("visibility","visible");}, function() {$("img", this).css("visibility","hidden");});


    $(".groupMenuPopup").mousedown(function(e) {        
        if (e.stopPropagation)
            e.stopPropagation();
        e.cancelBubble = true;
    });

    $(".friendsGroupsMenuPopup").mousedown(function(e) {
        if (e.stopPropagation)
            e.stopPropagation();
        e.cancelBubble = true;
        $(".groupMenuPopup").hide();
    });



    $(".groupMenuPopup .groupMenuPopupRename").click(function() {        
        var link = $("#ug"+activeFriendsGroupId+" a");
        $(".groupMenuPopup").hide();
        link.hide();
        link.after("<input id=\"groupName2\" type=\"text\" value=\""+escapequotes(link.html())+"\" />");
        var f = function(t) {
            if (link.html()!=t.value) {
                showwait();
                $.ajax({
                    url: pservicePath+"friends.jsp",
                    dataType: "html",
                    type: "POST",
                    data: {act: "renamegroup", groupid: activeFriendsGroupId, title:t.value, fkey: fkey},
                    cache: false,
                    success: function(data){
                        link.html(t.value);
                        $(t).remove();
                        link.show();
                        hidewait();
                    },
                    error: function() {
                        errorTemp = true;
                        hidewait(true);
                        alert("Error");
                        errorTemp = false;
                    }
                });
            } else {
                $(t).remove();
                link.show();
            }
        };
        $("#groupName2").keypress(function(e) {
            if (e.keyCode==13) f(this);
        }).blur(function() {if (!errorTemp) f(this)}).focus().select();
        //$(this).parent().hide();
        return false;
    });
   /* $(".friendsGroupsMenuPopup .groupMenuPopupCreate").click(function() {
        $(this).hide();
        $(this).next().show().focus().select();        
        return false;
    });*/

    $(".groupMenuPopup .groupMenuPopupRemove").click(function() {
        if (this.className.indexOf("disabled")>=0) return false;
        if (confirm("Вы действительно хотите удалить эту группу? Все контакты будут перемещены в группу Контакты.")) {
            showwait();
            $.ajax({
                url: pservicePath+"friends.jsp",
                dataType: "html",
                type: "POST",
                data: {act: "removegroup", groupid: activeFriendsGroupId, fkey: fkey},
                cache: false,
                success: function(data){
                    document.location.reload();
                },
                error: function() {
                    hidewait(true);
                    alert("Error");
                }
            });
        }
        $(this).parent().hide();
        return false;
    });

    $(".friendsGroupsMenuPopupItem img", parent).mouseup(function() {
        var m = $(".groupMenuPopup");
        var t = $(this);
        activeFriendsGroupId = t.parent().attr("id").substring(2);       
        m.css("left", (t.offset().left-4)+"px");
        m.css("top",(t.offset().top-4)+"px");
        //if (activeFriendsGroupId==0) {
        //    m.find(".groupMenuPopupRename,.groupMenuPopupRemove").hide();
        //} else {
        //    m.find(".groupMenuPopupRename,.groupMenuPopupRemove").show();
        //}
        
        m.show();
    }).click(function() {return false;});

    $(".friendsGroupsMenu a", parent).mouseup(function() {
        var m = $(".friendsGroupsMenuPopup");
        var t = $(this);
        m.css("left", (t.offset().left-4)+"px");
        m.css("top",(t.offset().top-4)+"px");        
        m.show();
    }).click(function() {return false;});;

    //$(".userGroup img").click(function() {alert("Вау! Ты нашел супер секретную функцию!!!");});
    $(".userGroupClose", parent).click(function() {
        var s = $(this).parent().next();
        var groupId = s.attr("id").substring(2);
        var op;
        if (this.className.indexOf("closed") >= 0) {
            //closed... open now!
            $(this).removeClass("closed");
            s.show();
            op = "opengroup";
        } else {
            //close!
            $(this).addClass("closed");
            s.hide();
            op = "closegroup";
        }
        $.ajax({
            url: pservicePath+"friends.jsp",
            dataType: "html",
            type: "POST",
            data: {act: op, groupid: groupId, fkey: fkey},
            cache: false,
            success: function(data){

            },
            error: function() {
                alert("Error");
            }
        });
        return false;
    });
}
/*
Clipboard - Copy utility for jQuery
Version 2.0 (packed)
November 24, 2007
Project page: http://bradleysepos.com/projects/jquery/clipboard/
*/
(function($){var flashMinVersion=[8,0,0];var flashDetectedVersion=[0,0,0];var swfpath;var debugging;var flashdetect=function(minVersion){var d=null;if(typeof navigator.plugins!="undefined"&&typeof navigator.plugins["Shockwave Flash"]=="object"){d=navigator.plugins["Shockwave Flash"].description;if(d){d=d.replace(/^.*\s+(\S+\s+\S+$)/,"$1");flashDetectedVersion[0]=parseInt(d.replace(/^(.*)\..*$/,"$1"),10);flashDetectedVersion[1]=parseInt(d.replace(/^.*\.(.*)\s.*$/,"$1"),10);if(/r/.test(d)){flashDetectedVersion[2]=parseInt(d.replace(/^.*r(.*)$/,"$1"),10)}else{flashDetectedVersion[2]=0}if(flashDetectedVersion[0]>minVersion[0]||(flashDetectedVersion[0]==minVersion[0]&&flashDetectedVersion[1]>minVersion[1])||(flashDetectedVersion[0]==minVersion[0]&&flashDetectedVersion[1]==minVersion[1]&&flashDetectedVersion[2]>=minVersion[2])){return true}else{return false}}}return false};var iecopydetect=function(){if(typeof window.clipboardData!="undefined"){return true}};var debug=function(string){if(debugging&&typeof console!="undefined"&&typeof console.log=="function"){console.log(string)}};var swfready=function(){if($.clipboardReady.done){return false}if(typeof $.clipboardReady.counter=='undefined'){$.clipboardReady.counter=0}$.clipboardReady.counter++;if($.clipboardReady.counter>599){clearInterval($.clipboardReady.timer);debug("Waited "+$.clipboardReady.counter/10+" seconds for Flash object to load, terminating.");return false}if(($.clipboardReady.counter%100)==0){debug("Waited "+$.clipboardReady.counter/10+" seconds for Flash object to load so far...")}var swf=$("#jquery_clipboard_swf:first");var swfdom=$(swf).get(0);if(typeof swfdom.jqueryClipboardCopy=="function"&&swfdom.jqueryClipboardAvailable){clearInterval($.clipboardReady.timer);$.clipboardReady.timer=null;$.clipboard.method='flash';for(var i=0;i<$.clipboardReady.ready.length;i++){$.clipboardReady.ready[i]()}$.clipboardReady.ready=null;$.clipboardReady.done=true;debug("jQuery.clipboard: OK. Initialized and ready to copy using Flash method.")}};$.clipboardReady=function(f,options){options=jQuery.extend({swfpath:staticPath+"js/jquery.clipboard.swf",debug:false},options);swfpath=options.swfpath;debugging=options.debug;if(iecopydetect()){$.clipboard.method='ie';debug("jQuery.clipboard: OK. Initialized and ready to copy using native IE method.");return f()}if($.clipboardReady.done){return f()}if($.clipboardReady.timer){$.clipboardReady.ready.push(f)}else{if(flashdetect(flashMinVersion)){$("#jquery_clipboard_swf").remove();$("#jquery_clipboard_div").remove();var div;div=$("<div/>").attr("id","jquery_clipboard_div").css("width","0").css("height","0").appendTo("body").html("");var swf;swf=$('<embed id="jquery_clipboard_swf" name="jquery_clipboard_swf" src="'+swfpath+'" type="application/x-shockwave-flash"></embed>');$(swf).css("width","0").css("height","0").appendTo(div);$.clipboardReady.ready=[f];$.clipboardReady.timer=setInterval(swfready,100);debug("jQuery.clipboard: INFO. Waiting for Flash object to become ready. Detected Flash version: "+flashDetectedVersion[0]+"."+flashDetectedVersion[1]+"."+flashDetectedVersion[2])}else if(flashDetectedVersion[0]===0){debug("jQuery.clipboard: ERROR. Flash plugin not detected.");return false}else{debug("jQuery.clipboard: ERROR. Minimum Flash version: "+flashMinVersion[0]+"."+flashMinVersion[1]+"."+flashMinVersion[2]+" Detected Flash version: "+flashDetectedVersion[0]+"."+flashDetectedVersion[1]+"."+flashDetectedVersion[2]);return false}}};$.clipboard=function(text){if(arguments.length<1||typeof text!="string"){debug("jQuery.clipboard: ERROR. Nothing to copy. You must specify a string as the first parameter.");return false}if($.clipboard.method=='ie'){try{window.clipboardData.setData("Text",text);debug("jQuery.clipboard: OK. Copied "+text.length+" bytes to clipboard using native IE method.");return true}catch(e){debug("jQuery.clipboard: ERROR. Tried to copy using native IE method but an unknown error occurred.");return false}}if($.clipboard.method=='flash'){var swf=$("#jquery_clipboard_swf:first");var swfdom=$(swf).get(0);if(swfdom.jqueryClipboardCopy(text)){debug("jQuery.clipboard: OK. Copied "+text.length+" bytes to clipboard using Flash method.");return true}else{debug("jQuery.clipboard: ERROR. Tried to copy using Flash method but an unknown error occurred.");return false}}debug("jQuery.clipboard: ERROR. You must use $.clipboardReady() in conjunction with $.clipboard().");return false}})(jQuery);

/*
 * jQuery Tooltip plugin 1.2
 *
 * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
 * http://docs.jquery.com/Plugins/Tooltip
 *
 * Copyright (c) 2006 - 2008 JГ¶rn Zaefferer
 *
 * $Id: jquery.tooltip.js 4569 2008-01-31 19:36:35Z joern.zaefferer $
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */;(function($){var helper={},current,title,tID,IE=$.browser.msie&&/MSIE\s(5\.5|6\.)/.test(navigator.userAgent),track=false;$.tooltip={blocked:false,defaults:{delay:200,showURL:true,extraClass:"",top:15,left:15,id:"tooltip"},block:function(){$.tooltip.blocked=!$.tooltip.blocked;}};$.fn.extend({tooltip:function(settings){settings=$.extend({},$.tooltip.defaults,settings);createHelper(settings);return this.each(function(){$.data(this,"tooltip-settings",settings);this.tooltipText=this.title;$(this).removeAttr("title");this.alt="";}).hover(save,hide).click(hide);},fixPNG:IE?function(){return this.each(function(){var image=$(this).css('backgroundImage');if(image.match(/^url\(["']?(.*\.png)["']?\)$/i)){image=RegExp.$1;$(this).css({'backgroundImage':'none','filter':"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='"+image+"')"}).each(function(){var position=$(this).css('position');if(position!='absolute'&&position!='relative')$(this).css('position','relative');});}});}:function(){return this;},unfixPNG:IE?function(){return this.each(function(){$(this).css({'filter':'',backgroundImage:''});});}:function(){return this;},hideWhenEmpty:function(){return this.each(function(){$(this)[$(this).html()?"show":"hide"]();});},url:function(){return this.attr('href')||this.attr('src');}});function createHelper(settings){if(helper.parent)return;helper.parent=$('<div id="'+settings.id+'"><h3></h3><div class="body"></div><div class="url"></div></div>').appendTo(document.body).hide();if($.fn.bgiframe)helper.parent.bgiframe();helper.title=$('h3',helper.parent);helper.body=$('div.body',helper.parent);helper.url=$('div.url',helper.parent);}function settings(element){return $.data(element,"tooltip-settings");}function handle(event){if(settings(this).delay)tID=setTimeout(show,settings(this).delay);else
show();track=!!settings(this).track;$(document.body).bind('mousemove',update);update(event);}function save(){if($.tooltip.blocked||this==current||(!this.tooltipText&&!settings(this).bodyHandler))return;current=this;title=this.tooltipText;if(settings(this).bodyHandler){helper.title.hide();var bodyContent=settings(this).bodyHandler.call(this);if(bodyContent.nodeType||bodyContent.jquery){helper.body.empty().append(bodyContent)}else{helper.body.html(bodyContent);}helper.body.show();}else if(settings(this).showBody){var parts=title.split(settings(this).showBody);helper.title.html(parts.shift()).show();helper.body.empty();for(var i=0,part;part=parts[i];i++){if(i>0)helper.body.append("<br/>");helper.body.append(part);}helper.body.hideWhenEmpty();}else{helper.title.html(title).show();helper.body.hide();}if(settings(this).showURL&&$(this).url())helper.url.html($(this).url().replace('http://','')).show();else
helper.url.hide();helper.parent.addClass(settings(this).extraClass);if(settings(this).fixPNG)helper.parent.fixPNG();handle.apply(this,arguments);}function show(){tID=null;helper.parent.show();update();}function update(event){if($.tooltip.blocked)return;if(!track&&helper.parent.is(":visible")){$(document.body).unbind('mousemove',update)}if(current==null){$(document.body).unbind('mousemove',update);return;}helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");var left=helper.parent[0].offsetLeft;var top=helper.parent[0].offsetTop;if(event){left=event.pageX+settings(current).left;top=event.pageY+settings(current).top;helper.parent.css({left:left+'px',top:top+'px'});}var v=viewport(),h=helper.parent[0];if(v.x+v.cx<h.offsetLeft+h.offsetWidth){left-=h.offsetWidth+20+settings(current).left;helper.parent.css({left:left+'px'}).addClass("viewport-right");}if(v.y+v.cy<h.offsetTop+h.offsetHeight){top-=h.offsetHeight+20+settings(current).top;helper.parent.css({top:top+'px'}).addClass("viewport-bottom");}}function viewport(){return{x:$(window).scrollLeft(),y:$(window).scrollTop(),cx:$(window).width(),cy:$(window).height()};}function hide(event){if($.tooltip.blocked)return;if(tID)clearTimeout(tID);current=null;helper.parent.hide().removeClass(settings(this).extraClass);if(settings(this).fixPNG)helper.parent.unfixPNG();}$.fn.Tooltip=$.fn.tooltip;})(jQuery);

jQuery.preloadImages = function()
{
  for(var i = 0; i<arguments.length; i++)
  {
    jQuery("<img>").attr("src", arguments[i]);
  }
};

/*
 *	jquery.suggest 1.1 - 2007-08-06
 *
 *	Uses code and techniques from following libraries:
 *	1. http://www.dyve.net/jquery/?autocomplete
 *	2. http://dev.jquery.com/browser/trunk/plugins/interface/iautocompleter.js
 *
 *	All the new stuff written by Peter Vulgaris (www.vulgarisoip.com)
 *	Feel free to do whatever you want with this file
 *
 */
function formatItem(row) {
    //var row = row.split("|");
    return row[0] + " (" + row[1] + ")";
};

function formatResult(row) {
    return row[0];
};

/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-03-19 16:02:41 +0100 (Mo, 19 Mrz 2007) $
 * $Rev: 1546 $
 */
(function($){$.fn.bgIframe=jQuery.fn.bgiframe=function(s){if(!($.browser.msie&&typeof XMLHttpRequest=='function'))return this;s=$.extend({top:'auto',left:'auto',width:'auto',height:'auto',opacity:true,src:'javascript:false;'},s||{});var prop=function(n){return n&&n.constructor==Number?n+'px':n;},html='<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"style="display:block;position:absolute;z-index:-1;'+(s.opacity!==false?'filter:Alpha(Opacity=\'0\');':'')+'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';"/>';return this.each(function(){if(!$('iframe.bgiframe',this)[0])this.insertBefore(document.createElement(html),this.firstChild);});};})(jQuery);

/**
 * Provide autocomplete for text-inputs or textareas.
 *
 * Depends on dimensions plugin's offset method for correct positioning of the select box and bgiframe plugin
 * to fix IE's problem with selects.
 *
 * @example $("#input_box").autocomplete("my_autocomplete_backend.php");
 * @before <input id="input_box" />
 * @desc Autocomplete a text-input with remote data. For small to giant datasets.
 *
 * When the user starts typing, a request is send to the specified backend ("my_autocomplete_backend.php"),
 * with a GET parameter named q that contains the current value of the input box and a paremeter "limit" with
 * the value specified for the max option.
 *
 * A value of "foo" would result in this request url: my_autocomplete_backend.php?q=foo&limit=10
 *
 * The result must return with one value on each line. The result is presented in the order
 * the backend sends it.
 *
 * @example $("#input_box").autocomplete(["Cologne", "Berlin", "Munich"]);
 * @before <input id="input_box" />
 * @desc Autcomplete a text-input with local data. For small datasets.
 *
 * @example $.getJSON("my_backend.php", function(data) {
 *   $("#input_box").autocomplete(data);
 * });
 * @before <input id="input_box" />
 * @desc Autcomplete a text-input with data received via AJAX. For small to medium sized datasets.
 *
 * @example $("#mytextarea").autocomplete(["Cologne", "Berlin", "Munich"], {
 *  multiple: true
 * });
 * @before <textarea id="mytextarea" />
 * @desc Autcomplete a textarea with local data (for small datasets). Once the user chooses one
 * value, a separator is appended (by default a comma, see multipleSeparator option) and more values
 * are autocompleted.
 *
 * @name autocomplete
 * @cat Plugins/Autocomplete
 * @type jQuery
 * @param String|Array urlOrData Pass either an URL for remote-autocompletion or an array of data for local auto-completion
 * @param Map options Optional settings
 * @option String inputClass This class will be added to the input box. Default: "ac_input"
 * @option String resultsClass The class for the UL that will contain the result items (result items are LI elements). Default: "ac_results"
 * @option String loadingClass The class for the input box while results are being fetched from the server. Default: "ac_loading"
 * @option Number minChars The minimum number of characters a user has to type before the autocompleter activates. Default: 1
 * @option Number delay The delay in milliseconds the autocompleter waits after a keystroke to activate itself. Default: 400 for remote, 10 for local
 * @option Number cacheLength The number of backend query results to store in cache. If set to 1 (the current result), no caching will happen. Do not set below 1. Default: 10
 * @option Boolean matchSubset Whether or not the autocompleter can use a cache for more specific queries. This means that all matches of "foot" are a subset of all matches for "foo". Usually this is true, and using this options decreases server load and increases performance. Only useful with cacheLength settings bigger then one, like 10. Default: true
 * @option Boolean matchCase Whether or not the comparison is case sensitive. Only important only if you use caching. Default: false
 * @option Boolean matchContains Whether or not the comparison looks inside (i.e. does "ba" match "foo bar") the search results. Only important if you use caching. Don't mix with autofill. Default: false
 * @option Booolean mustMatch If set to true, the autocompleter will only allow results that are presented by the backend. Note that illegal values result in an empty input box. Default: false
 * @option Object extraParams Extra parameters for the backend. If you were to specify { bar:4 }, the autocompleter would call my_autocomplete_backend.php?q=foo&bar=4 (assuming the input box contains "foo"). Default: {}
 * @option Boolean selectFirst If this is set to true, the first autocomplete value will be automatically selected on tab/return, even if it has not been handpicked by keyboard or mouse action. If there is a handpicked (highlighted) result, that result will take precedence. Default: true
 * @option Function formatItem Provides advanced markup for an item. For each row of results, this function will be called. The returned value will be displayed inside an LI element in the results list. Autocompleter will provide 3 parameters: the results row, the position of the row in the list of results (starting at 1), and the number of items in the list of results. Default: none, assumes that a single row contains a single value.
 * @option Function formatResult Similar to formatResult, but provides the formatting for the value to be put into the input field. Again three arguments: Data, position (starting with one) and total number of data. Default: none, assumes either plain data to use as result or uses the same value as provided by formatItem.
 * @option Boolean multiple Whether to allow more then one autocomplted-value to enter. Default: false
 * @option String multipleSeparator Seperator to put between values when using multiple option. Default: ", "
 * @option Number width Specify a custom width for the select box. Default: width of the input element
 * @option Boolean autoFill Fill the textinput while still selecting a value, replacing the value if more is type or something else is selected. Default: false
 * @option Number max Limit the number of items in the select box. Is also send as a "limit" parameter with a remote request. Default: 10
 */

/**
 * Handle the result of a search event. Is executed when the user selects a value or a
 * programmatic search event is triggered (see search()).
 *
 * You can add and remove (using unbind("result")) this event at any time.
 *
 * @example jQuery('input#suggest').result(function(event, data, formatted) {
 *   jQuery("#result").html( !data ? "No match!" : "Selected: " + formatted);
 * });
 * @desc Bind a handler to the result event to display the selected value in a #result element.
 *    The first argument is a generic event object, in this case with type "result".
 *    The second argument refers to the selected data, which can be a plain string value or an array or object.
 *    The third argument is the formatted value that is inserted into the input field.
 *
 * @param Function handler The event handler, gets a default event object as first and
 * 		the selected list item as second argument.
 * @name result
 * @cat Plugins/Autocomplete
 * @type jQuery
 */

/**
 * Trigger a search event. See result(Function) for binding to that event.
 *
 * A search event mimics the same behaviour as when the user selects a value from
 * the list of autocomplete items. You can use it to execute anything that does something
 * with the selected value, beyond simply putting the value into the input and submitting it.
 *
 * @example jQuery('input#suggest').search();
 * @desc Triggers a search event.
 *
 * @name search
 * @cat Plugins/Autocomplete
 * @type jQuery
 */

// * @option Function onSelectItem Called when an item is selected. The autocompleter will specify a single argument, being the LI element selected. This LI element will have an attribute "extra" that contains an array of all cells that the backend specified. Default: none

jQuery.fn.extend({
    autocomplete: function(urlOrData, options) {
        var isUrl = typeof urlOrData == "string";
        options = jQuery.extend({}, jQuery.Autocompleter.defaults, {
            url: isUrl ? urlOrData : null,
            data: isUrl ? null : urlOrData,
            delay: isUrl ? jQuery.Autocompleter.defaults.delay : 10
        }, options);
        return this.each(function() {
            new jQuery.Autocompleter(this, options);
        });
    },
    result: function(handler) {
        return this.bind("result", handler);
    },
    search: function() {
        return this.trigger("search");
    }
});

jQuery.Autocompleter = function(input, options) {

    var KEY = {
        UP: 38,
        DOWN: 40,
        DEL: 46,
        TAB: 9,
        RETURN: 13,
        ESC: 27,
        COMMA: 188
    };

    // Create jQuery object for input element
    var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);

    var timeout;
    var previousValue = "";
    var cache = jQuery.Autocompleter.Cache(options);
    var hasFocus = 0;
    var lastKeyPressCode;
    var select = jQuery.Autocompleter.Select(options, input, selectCurrent);

    $input.keydown(function(event) {
        // track last key pressed
        lastKeyPressCode = event.keyCode;
        switch(event.keyCode) {

            case KEY.UP:
                event.preventDefault();
                if ( select.visible() ) {
                    select.prev();
                } else {
                    onChange(0, true);
                }
                break;

            case KEY.DOWN:
                event.preventDefault();
                if ( select.visible() ) {
                    select.next();
                } else {
                    onChange(0, true);
                }
                break;

            // matches also semicolon
            case options.multiple && jQuery.trim(options.multipleSeparator) == "," && KEY.COMMA:
            case KEY.TAB:
            case KEY.RETURN:
                if( selectCurrent() ){
                    // make sure to blur off the current field
                    if( !options.multiple )
                        $input.blur();
                    event.preventDefault();
                }
                break;

            case KEY.ESC:
                select.hide();
                break;

            default:
                clearTimeout(timeout);
                timeout = setTimeout(onChange, options.delay);
                break;
        }
    }).keypress(function() {
        // having fun with opera - remove this binding and Opera submits the form when we select an entry via return
    }).focus(function(){
        // track whether the field has focus, we shouldn't process any
        // results if the field no longer has focus
        hasFocus++;
    }).blur(function() {
        hasFocus = 0;
        hideResults();
    }).click(function() {
        // show select when clicking in a focused field
        if ( hasFocus++ > 1 && !select.visible() ) {
            onChange(0, true);
        }
    }).bind("search", function() {
        function findValueCallback(q, data) {
            var result;
            if( data && data.length ) {
                for (var i=0; i < data.length; i++) {
                    if( data[i].result.toLowerCase() == q.toLowerCase() ) {
                        result = data[i];
                        break;
                    }
                }
            }
            $input.trigger("result", result && [result.data, result.value]);
        }
        jQuery.each(trimWords($input.val()), function(i, value) {
            request(value, findValueCallback, findValueCallback);
        });
    });

    hideResultsNow();

    function selectCurrent() {
        var selected = select.selected();
        if( !selected )
            return false;

        var v = selected.result;
        previousValue = v;

        if ( options.multiple ) {
            var words = trimWords($input.val());
            if ( words.length > 1 ) {
                v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
            }
            v += options.multipleSeparator;
        }

        $input.val(v);
        hideResultsNow();
        $input.trigger("result", [selected.data, selected.value]);
        return true;
    }

    function onChange(crap, skipPrevCheck) {
        if( lastKeyPressCode == KEY.DEL ) {
            select.hide();
            return;
        }

        var currentValue = $input.val();

        if ( !skipPrevCheck && currentValue == previousValue )
            return;

        previousValue = currentValue;

        currentValue = lastWord(currentValue);
        if ( currentValue.length >= options.minChars) {
            $input.addClass(options.loadingClass);
            if (!options.matchCase)
                currentValue = currentValue.toLowerCase();
            request(currentValue, receiveData, stopLoading);
        } else {
            stopLoading();
            select.hide();
        }
    };

    function trimWords(value) {
        if ( !value ) {
            return [""];
        }
        var words = value.split( jQuery.trim( options.multipleSeparator ) );
        var result = [];
        jQuery.each(words, function(i, value) {
            if ( jQuery.trim(value) )
                result[i] = jQuery.trim(value);
        });
        return result;
    }

    function lastWord(value) {
        if ( !options.multiple )
            return value;
        var words = trimWords(value);
        return words[words.length - 1];
    }

    // fills in the input box w/the first match (assumed to be the best match)
    function autoFill(q, sValue){
        // autofill in the complete box w/the first match as long as the user hasn't entered in more data
        // if the last user key pressed was backspace, don't autofill
        if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != 8 ) {
            // fill in the value (keep the case the user has typed)
            $input.val($input.val() + sValue.substring(lastWord(previousValue).length));
            // select the portion of the value not typed by the user (so the next character will erase)
            jQuery.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
        }
    };

    function hideResults() {
        clearTimeout(timeout);
        timeout = setTimeout(hideResultsNow, 200);
    };

    function hideResultsNow() {
        select.hide();
        clearTimeout(timeout);
        stopLoading();
        // TODO fix mustMatch...
        if (options.mustMatch) {
            if ($input.val() != previousValue) {
                //selectCurrent();
            }
        }
    };

    function receiveData(q, data) {
        if ( data && data.length && hasFocus ) {
            stopLoading();
            select.display(data, q);
            autoFill(q, data[0].value);
            select.show();
        } else {
            hideResultsNow();
        }
    };

    function request(term, success, failure) {
        if (!options.matchCase)
            term = term.toLowerCase();
        var data = cache.load(term);
        // recieve the cached data
        if (data && data.length) {
            success(term, data);
            // if an AJAX url has been supplied, try loading the data now
        } else if( (typeof options.url == "string") && (options.url.length > 0) ){
            jQuery.ajax({
                url: options.url,
                data: jQuery.extend({
                    q: lastWord(term),
                    limit: options.max
                }, options.extraParams),
                success: function(data) {
                    var parsed = options.parse && options.parse(data) || parse(data);
                    cache.add(term, parsed);
                    success(term, parsed);
                }
            });
        } else {
            failure(term);
        }
    }

    function parse(data) {
        var parsed = [];
        var rows = data.split("\n");
        for (var i=0; i < rows.length; i++) {
            var row = jQuery.trim(rows[i]);
            if (row) {
                row = row.split("|");
                parsed[parsed.length] = {
                    data: row,
                    value: row[0],
                    result: options.formatResult && options.formatResult(row) || row[0]
                };
            }
        }
        return parsed;
    }

    function stopLoading() {
        $input.removeClass(options.loadingClass);
    }

}

jQuery.Autocompleter.defaults = {
    inputClass: "ac_input",
    resultsClass: "ac_results",
    loadingClass: "ac_loading",
    minChars: 1,
    delay: 400,
    matchCase: false,
    matchSubset: true,
    matchContains: false,
    cacheLength: 10,
    mustMatch: false,
    extraParams: {},
    selectFirst: true,
    max: 10,
//size: 10,
    autoFill: false,
    width: 0,
    multiple: false,
    multipleSeparator: ", "
};

jQuery.Autocompleter.Cache = function(options) {

    var data = {};
    var length = 0;

    function matchSubset(s, sub) {
        if (!options.matchCase)
            s = s.toLowerCase();
        var i = s.indexOf(sub);
        if (i == -1) return false;
        return i == 0 || options.matchContains;
    };

    function add(q, value) {
        if (length > options.cacheLength) {
            this.flush();
        }
        if (!data[q]) {
            length++;
        }
        data[q] = value;
    }

    // if there is a data array supplied
    if( options.data ){
        var stMatchSets = {},
                nullData = 0;

        // no url was specified, we need to adjust the cache length to make sure it fits the local data store
        if( !options.url ) options.cacheLength = 1;

        stMatchSets[""] = [];

        // loop through the array and create a lookup structure
        jQuery.each(options.data, function(i, rawValue) {
            // if row is a string, make an array otherwise just reference the array


            value = options.formatItem
                    ? options.formatItem(rawValue, i+1, options.data.length)
                    : rawValue;
            var firstChar = value.charAt(0).toLowerCase();
            // if no lookup array for this character exists, look it up now
            if( !stMatchSets[firstChar] )
                stMatchSets[firstChar] = [];
            // if the match is a string
            var row = {
                value: value,
                data: rawValue,
                result: options.formatResult && options.formatResult(rawValue) || value
            }

            stMatchSets[firstChar].push(row);

            if ( nullData++ < options.max ) {
                stMatchSets[""].push(row);
            }

        });

        // add the data items to the cache
        jQuery.each(stMatchSets, function(i, value) {
            // increase the cache size
            options.cacheLength++;
            // add to the cache
            add(i, value);
        });
    }

    return {
        flush: function() {
            data = {};
            length = 0;
        },
        add: add,
        load: function(q) {
            if (!options.cacheLength || !length)
                return null;
            if (data[q])
                return data[q];
            if (options.matchSubset) {
                for (var i = q.length - 1; i >= options.minChars; i--) {
                    var c = data[q.substr(0, i)];
                    if (c) {
                        var csub = [];
                        jQuery.each(c, function(i, x) {
                            if (matchSubset(x.value, q)) {
                                csub[csub.length] = x;
                            }
                        });
                        return csub;
                    }
                }
            }
            return null;
        }
    };
};

jQuery.Autocompleter.Select = function (options, input, select) {
    var CLASSES = {
        ACTIVE: "ac_over"
    };

    // Create results
    var element = jQuery("<div>")
            .hide()
            .addClass(options.resultsClass)
            .css("position", "absolute")
            .appendTo("body");

    var list = jQuery("<ul>").appendTo(element).mouseover( function(event) {
        active = jQuery("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
        jQuery(target(event)).addClass(CLASSES.ACTIVE);
    }).mouseout( function(event) {
        jQuery(target(event)).removeClass(CLASSES.ACTIVE);
    }).click(function(event) {
        jQuery(target(event)).addClass(CLASSES.ACTIVE);
        select();
        input.focus();
        return false;
    });
    var listItems,
            active = -1,
            data,
            term = "";

    if( options.width > 0 )
        element.css("width", options.width);

    function target(event) {
        var element = event.target;
        while(element.tagName != "LI")
            element = element.parentNode;
        return element;
    }

    function moveSelect(step) {
        active += step;
        wrapSelection();
        listItems.removeClass(CLASSES.ACTIVE).eq(active).addClass(CLASSES.ACTIVE);
    };

    function wrapSelection() {
        if (active < 0) {
            active = listItems.size() - 1;
        } else if (active >= listItems.size()) {
            active = 0;
        }
    }

    function limitNumberOfItems(available) {
        return (options.max > 0) && (options.max < available)
                ? options.max
                : available;
    }

    function dataToDom() {
        var num = limitNumberOfItems(data.length);
        for (var i=0; i < num; i++) {
            if (!data[i])
                continue;
            function highlight(value) {
                return value.replace(new RegExp("(" + term + ")", "gi"), "<strong>$1</strong>");
            }
            jQuery("<li>").html( options.formatItem
                    ? highlight(options.formatItem(data[i].data, i+1, num))
                    : highlight(data[i].value) ).appendTo(list);
        }
        listItems = list.find("li");
        if ( options.selectFirst ) {
            listItems.eq(0).addClass(CLASSES.ACTIVE);
            active = 0;
        }
    }

    return {
        display: function(d, q) {
            data = d;
            term = q;
            list.empty();
            dataToDom();
            list.bgiframe();
        },
        next: function() {
            moveSelect(1);
        },
        prev: function() {
            moveSelect(-1);
        },
        hide: function() {
            element.hide();
            active = -1;
        },
        visible : function() {
            return element.is(":visible");
        },
        current: function() {
            return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
        },
        show: function() {
            // get the position of the input field right now (in case the DOM is shifted)
            var offset = jQuery(input).offset({scroll: false, border: false});
            // either use the specified width, or autocalculate based on form element
            element.css({
                width: options.width > 0 ? options.width : jQuery(input).width(),
            //height: jQuery(listItems[0]).height() * options.size,
                top: offset.top + input.offsetHeight,
                left: offset.left
            }).show();
            //active = -1;
            //listItems.removeClass(CLASSES.ACTIVE);
        },
        selected: function() {
            return data && data[active];
        }
    };
}

jQuery.Autocompleter.Selection = function(field, start, end) {
    if( field.createTextRange ){
        var selRange = field.createTextRange();
        selRange.collapse(true);
        selRange.moveStart("character", start);
        selRange.moveEnd("character", end);
        selRange.select();
    } else if( field.setSelectionRange ){
        field.setSelectionRange(start, end);
    } else {
        if( field.selectionStart ){
            field.selectionStart = start;
            field.selectionEnd = end;
        }
    }
    field.focus();
};

function fastComment(t,type,pid,puid) {
    if (logged==0) registerfirst(); else {
        var p = $(t).parent();
        if (p.nextAll(".feedItemFastComment").length == 0) {
            //add form
            var f = $('<div class="feedItemFastComment"><form method="post" onsubmit="return postFastComment(this,'+type+','+pid+','+puid+')">' +
                      '<div class="feedItemFastCommentText"><textarea></textarea></div>' +
                      '<div class="clear100"><a href="#" class="button1" onclick="return postFastComment(this,'+type+','+pid+','+puid+')">Отправить</a></div>' +
                      '<input type="submit" value="" style="display:none" />' +
                      '</form></div>');
            if (p.next().length!=0) p = p.next();
            p.after(f);
            $("textarea", f).select();
            $("textarea", f).keypress(function(e) {if ((e.keyCode==13 || e.keyCode==10) && e.ctrlKey) {$(this).parent().next().children("a").click();}});
        } else p.nextAll(".feedItemFastComment").remove();
    }
    return false;
};
function postFastComment(t,type,pid,puid) {
    if (logged==0) registerfirst(); else {
        var tp = $(t).parents(".feedItemFastComment");
        var text = tp.find("textarea").val();
        if (text.length==0) {alert("Введите текст комментария!");return false;}
        showwait();
        $.ajax({
            url: pservicePath + "comments.jsp",
            dataType: "html",
            type: "POST",
            data: {pid: pid, act: "add", text:text, cid: 0, type: type, fkey: fkey, puid: puid},
            cache: false,
            success: function(data){
                if (data!="OK") {
                    hidewait(true);alert(data);
                } else {
                    //var tp = $(t).parent();
                    tp.prevAll(".feedItemControlComments").find("a").attr("onclick","");
                    tp.prevAll(".feedItemControlComments").find("a span").html("1");
                    tp.remove();
                    hidewait();
                }
            },
            error: function() {
                hidewait(true);
                alert("Error");
            }
        });
    }
    return false;
};
/* popup window */
function chatOpenPopup(url, name, nw, nh) {
    var w_w = nw ? nw : 550, w_h = nh ? nh : 500;
    var w = window.open(url, name, 'width=' + w_w + ',height=' + w_h + ',location=1,status=1,resizable=yes,scrollbars=1');

    var coords = getCenteredCoords(w_w, w_h);
    w.moveTo(coords[0],coords[1]);
    return false;
};
function getCenteredCoords(width, height) {
    var xPos = null;
    var yPos = null;
    if (window.ActiveXObject) {
        xPos = window.event.screenX - (width/2) + 100;
        yPos = window.event.screenY - (height/2) - 100;
    } else {
        var parentSize = [window.outerWidth, window.outerHeight];
        var parentPos = [window.screenX, window.screenY];
        xPos = parentPos[0] +
               Math.max(0, Math.floor((parentSize[0] - width) / 2));
        yPos = parentPos[1] +
               Math.max(0, Math.floor((parentSize[1] - (height*1.25)) / 2));
    }
    return [xPos, yPos];
};
