function Friends(sid, friend_cats) {
    var oThis = this;
    
    this.popup_win = null;
    
    this.is_control_pressed = false;
    
    friend_cats = friend_cats || [];
    
    var tr = {
        'PROFILE_SELECT_FRIEND_GROUP': 'select group',
        'PROFILE_ADD_FRIEND': 'Add to friends',
        'PROFILE_ADD_FRIEND_BTN': 'Add',
        'PROFILE_CLOSE_BTN': 'Close',
        'PROFILE_ADD_FRIEND_DESC': 'Select a group in which to add your friend:',
        'PROFILE_CREATE_FRIEND_GROUP': 'create new group',
        'PROFILE_INVITE_FRIEND_BTN': 'Send invitation',
        'PROFILE_WRITE_MESSAGE': 'write a message',
        'PROFILE_REMOVE_FRIEND_TITLE': 'Remove user from friends',
        'PROFILE_REMOVE_FRIEND_DESC': 'Do you want to remove {$user_name} from friends?',
        'PROFILE_REMOVE_FRIEND_BTN': 'Remove user'
    }
    
    this.showIgnoreRemove = function(user_id, link) {
        if (this.popup_win) {
            this.popup_win.hide();
            delete this.popup_win;
        }
        
        this.popup_win = new PopupWindow(tr['MODULES_IGNORED_REMOVE_TITLE'], 'dialog-std');
        
        function buttons() {
            return [new Button(tr['MODULES_IGNORED_REMOVE_BTN'], 'input-submit', function () {this.disabled=true; oThis.ignore_remove(user_id, this, link)} ),
                    new Button(tr['MODULES_IGNORED_CLOSE_BTN'], 'input-button', function () {oThis.popup_win.hide(); delete oThis.popup_win;} ) ];
        }
        function content() {
            var cont = document.createElement('div');
            
            cont.appendChild(document.createTextNode(tr['MODULES_IGNORED_REMOVE_DESC']));
            
            return cont;
        }
        
        var cont = document.body.firstChild.nodeType == 1 && document.body.firstChild || nextNode(document.body.firstChild);
        this.popup_win.display(cont, content, buttons, 'center');
    }
    
        this.ignore_remove = function (user_id, btn, link) {
            var request = {
                url: '/users/ajax_handle.do?action=remove_ignored',
                data: {
                    user_id: user_id
                },
                onSuccess: function (res) {
                    oThis.popup_win.hide();
                    delete oThis.popup_win;
                    
                    fadeOut(link.parentNode, 70, function () {link.parentNode.parentNode.removeChild(link.parentNode);});
                },
                onFailure: function (res) {
                    oThis.popup_win.showError(res);
                    setTimeout(function () {btn.disabled = false;}, 1000);
                }
            }
            
            AJAX(request);
        }
    
    
    this.showApproveFriend = function (user_id, link, name) {
        if (this.popup_win) {
            this.popup_win.hide();
            delete this.popup_win;
        }
        
        if (!user_id) {
            user_id = new Object();
            var list = document.getElementsByName(name);
            for(var i=0; i<list.length; i++) {
                if (list[i].checked == true)
                    user_id[list[i].value] = list[i].value;
            }
        }
        
        var select = new DropDown(tr['PROFILE_SELECT_FRIEND_GROUP'], 'dropdown-std', null);
        
        this.popup_win = new PopupWindow(tr['PROFILE_ADD_FRIEND'], 'dialog-std');
        
        
        function buttons() {
            return [new Button(tr['PROFILE_ADD_FRIEND_BTN'], 'input-submit', function () {this.disabled=true; oThis.approve_friend(user_id, select.getValue(), this, link, name)} ),
                    new Button(tr['PROFILE_CLOSE_BTN'], 'input-button', function () {oThis.popup_win.hide(); delete oThis.popup_win;} ) ];
        }
        function content() {
            var cont = document.createElement('div'),
                add_elements = new Array(),
                add_cat = document.createElement('input');
            
            cont.appendChild(document.createTextNode(tr['PROFILE_ADD_FRIEND_DESC']));
            
            /*add_cat.className = 'input-std';
            add_cat.value = tr['PROFILE_CREATE_FRIEND_GROUP'];
            add_cat.onfocus = function () {if (this.value == tr['PROFILE_CREATE_FRIEND_GROUP']) this.value = '';};
            add_cat.onblur = function () {if (this.value == '') this.value = tr['PROFILE_CREATE_FRIEND_GROUP'];};
            add_cat.onkeydown = function (event) {var value = this.value;oThis.get_key(event, function () {oThis.add_friends_group(value, select)});};
            
            add_elements.push(add_cat);
            
            var options = new Array();
            for(var i=0; i<friend_cats.length; i++) {
                var opt = new DropDownOption(friend_cats[i].title, friend_cats[i].id, function (event) {select.selectOption(event, this.v, this.t);});
                options.push(opt);
            }
            
            select.setOptions(options);
            select.init();
            select.addElements(add_elements);
            cont.appendChild(select.get());*/
            
            return cont;
        }
        
        var cont = document.body.firstChild.nodeType == 1 && document.body.firstChild || nextNode(document.body.firstChild);
        this.popup_win.display(cont, content, buttons, 'center');
    }
    
    
    this.approve_friend = function (user_id, group_id, btn, link, name) {
        var request = {
            url: '/users/ajax_handle.do?action=approve_friend',
            data: {
                friend_id: user_id,
                group_id: group_id
            },
            onSuccess: function (res) {
                oThis.popup_win.hide();
                delete oThis.popup_win;
                
                if (typeof(user_id) == 'object') {
                    var list = document.getElementsByName(name),
                        is_all = true;
                    
                    for(var i=0; i<list.length; i++) {
                        if(user_id[list[i].value]) {
                            list[i].checked = false;
                            fadeOut(list[i].parentNode, 50);
                        } else {
                            is_all = false;
                        }
                    }
                    if (is_all) location.reload();
                } else {
                    fadeOut(link, 50, function () {link.parentNode.removeChild(link);});
                }
            },
            onFailure: function (res) {
                oThis.popup_win.showError(res);
                setTimeout(function () {btn.disabled = false;}, 1000);
            }
        }
        
        AJAX(request);
    }
    
    this.showRemoveInvite = function (user_id, link, name) {
        if (this.popup_win) {
            this.popup_win.hide();
            delete this.popup_win;
        }
        
        if (!user_id) {
            user_id = new Object();
            var list = document.getElementsByName(name);
            for(var i=0; i<list.length; i++) {
                if (list[i].checked == true)
                    user_id[list[i].value] = list[i].value;
            }
        }
        
        this.popup_win = new PopupWindow(tr['PROFILE_REMOVE_INVITE'], 'dialog-std');
        
        
        function buttons() {
            return [new Button(tr['PROFILE_REMOVE_INVITE_BTN'], 'input-submit', function () {this.disabled=true; oThis.remove_invite(user_id, this, link, name)} ),
                    new Button(tr['PROFILE_CLOSE_BTN'], 'input-button', function () {oThis.popup_win.hide(); delete oThis.popup_win;} ) ];
        }
        function content() {
            var cont = document.createElement('div');
            
            cont.appendChild(document.createTextNode(tr['PROFILE_REMOVE_INVITE_DESC']));
            
            return cont;
        }
        
        var cont = document.body.firstChild.nodeType == 1 && document.body.firstChild || nextNode(document.body.firstChild);
        this.popup_win.display(cont, content, buttons, 'center');
    }
    
    this.remove_invite = function (user_id, btn, link, name) {
        var request = {
            url: '/users/ajax_handle.do?action=remove_invite',
            data: {
                friend_id: user_id
            },
            onSuccess: function (res) {
                oThis.popup_win.hide(); delete oThis.popup_win;
                
                if (typeof(user_id) == 'object') {
                    var list = document.getElementsByName(name),
                        is_all = true;
                    
                    for(var i=0; i<list.length; i++) {
                        if(user_id[list[i].value]) {
                            list[i].checked = false;
                            fadeOut(list[i].parentNode, 30);
                        } else {
                            is_all = false;
                        }
                    }
                    if (is_all) location.reload();
                } else {
                    fadeOut(link, 30, function () {link.parentNode.removeChild(link);});
                }
                
                
            },
            onFailure: function (res) {
                oThis.popup_win.hide(); delete oThis.popup_win;
                
                if (typeof(user_id) == 'object') {
                } else {
                    fadeOut(link, 30, function () {link.parentNode.removeChild(link);});
                }
            }
        };
        AJAX(request);
    }
    
    this.showAddFriend = function (usr_key) {
        if (this.popup_win) return;
        
        var select = new DropDown(tr['PROFILE_SELECT_FRIEND_GROUP'], 'dropdown-std', null),
            msg = document.createElement('textarea');
        
        this.popup_win = new PopupWindow('Add Friend', 'dialog-std');
        
        
        function buttons() {
            return [new Button(tr['PROFILE_INVITE_FRIEND_BTN'], 'input-submit', function () {this.disabled=true; oThis.add_friend(usr_key, msg, this)} ),
                    new Button(tr['PROFILE_CLOSE_BTN'], 'input-button', function () {oThis.popup_win.hide(); delete oThis.popup_win;} ) ];
        }
        function content() {
            var cont = document.createElement('div'),
                add_elements = new Array(),
                add_cat = document.createElement('input'),
                add_msg_cont = document.createElement('div'),
                add_msg_a = document.createElement('a');
            
            msg.className = 'textarea-std';
            msg.style.display = 'none';
            msg.onblur = function () {if (this.value == '') hide(this);};
            
            add_msg_a.href = '#';
            add_msg_a.appendChild(document.createTextNode(tr['PROFILE_WRITE_MESSAGE']));
            add_msg_a.onclick = function (event) {
                toggle(msg);
                
                if (msg.style.display == 'block') msg.focus();
                
                if (!event) event = window.event;
                
                if (event.stopPropagation) event.stopPropagation();
                event.cancelBubble = true;
                
                msg.onclick = function (e) {
                    if (!e) e = window.event;
                    
                    if (e.stopPropagation) e.stopPropagation();
                    e.cancelBubble = true;
                }
                
                document.onclick = function (e) {
                    if (!e) e = window.event;
                    
                    var rightclick = false;
                    
                    if (e.which) rightclick = (e.which == 3);
                    else if (e.button) rightclick = (e.button == 2);
                    
                    if (rightclick) return;
                    
                    if (msg.value == '') {
                        hide(msg);
                    }
                    
                    document.onclick = function (){};
                }
                
                return false;
            };
            
            add_msg_cont.style.zoom = 1;
            add_msg_cont.style.margin = '0 0 10px 0';
            add_msg_cont.appendChild(add_msg_a);
            add_msg_cont.appendChild(msg);
            cont.appendChild(add_msg_cont);
            
            return cont;
        }
        
        var cont = document.body.firstChild.nodeType == 1 && document.body.firstChild || nextNode(document.body.firstChild);
        this.popup_win.display(cont, content, buttons, 'center');
    }
    
        this.add_friend = function (usr_key, msg, btn) {
            var message = '';
            
            if (msg.style.display != 'none') message = msg.value;
            
            var request = {
                url: '/ajax/friend_request.do?f='+usr_key+'&key='+sid,
                data: { msg: message },
                onSuccess: function (res) {
                    oThis.popup_win.removeButtons();
                    oThis.popup_win.addButton(new Button(tr['PROFILE_CLOSE_BTN'], 'input-button', function () {oThis.popup_win.hide(); delete oThis.popup_win;} ));
                    oThis.popup_win.showMessage(res);
                    btn.disabled = false;
                },
                onFailure: function (res) {
                    oThis.popup_win.showError(res);
                    btn.disabled = false;
                }
            };
            AJAX(request);
        }
        
        this.add_friends_group = function (title, select) {
            var request = {
                url: '/users/ajax_handle.do?action=add_friend_group',
                data: {
                    title: title
                },
                onSuccess: function (res) {
                    var cat_id = eval('('+res+')');
                    
                    if (select) {
                        select.addOption(title, cat_id, function (event) {select.selectOption(event, this.v, this.t);});
                        select.selectOption (null, cat_id, title);
                    }
                    
                    friend_cats.push({"title": title, "id": cat_id});
                }
            };
            AJAX(request);
        }
    
    this.showRemoveGroup = function (group_id, link) {
        if (this.popup_win) {
            this.popup_win.hide();
            delete this.popup_win;
        }
        
        this.popup_win = new PopupWindow(tr['PROFILE_REMOVE_FRIEND_GROUP_TITLE'], 'dialog-std');
        
        function buttons() {
            return [new Button(tr['PROFILE_REMOVE_BTN'], 'input-submit', function () {this.disabled=true; oThis.remove_friends_group(group_id, link)} ),
                    new Button(tr['PROFILE_CLOSE_BTN'], 'input-button', function () {oThis.popup_win.hide(); delete oThis.popup_win;} ) ];
        }
        function content() {
            var cont = document.createElement('div');
            
            cont.appendChild(document.createTextNode(tr['PROFILE_REMOVE_FRIEND_GROUP_DESC']));
            
            return cont;
        }
        
        var cont = document.body.firstChild.nodeType == 1 && document.body.firstChild || nextNode(document.body.firstChild);
        this.popup_win.display(cont, content, buttons, 'center');
    }
    
    
    this.remove_friends_group = function (group_id, link) {
        var request = {
            url: '/users/ajax_handle.do?action=remove_friend_group',
            data: {
                group_id: group_id
            },
            onSuccess: function (res) {
                if (oThis.popup_win) {
                    oThis.popup_win.hide();
                    delete oThis.popup_win;
                }
                
                delete friend_cats[group_id];
                
                fadeOut(link, 50, function () {link.parentNode.removeChild(link)});
            }
        };
        AJAX(request);
    }
    
    this.renameGroup = function (e, group_id, title, obj) {
        if (!e) {
            e = window.event;
        }
        if (e.keyCode == 32 || e.keyCode > 40 || e.keyCode == 8) {
            if (obj.timeOut) {
                clearTimeout(obj.timeOut);
            }
            
            if (!$("group_save_aj")) {
               var save = document.createElement("div");
               save.className = "aj-save";
               save.id = "group_save_aj";
               save.style.display = "none";
               save.innerHTML = "saving..";
               obj.parentNode.appendChild(save);
            } else {
                var save = $("group_save_aj");
                hide(save);
            }
            
            if ($('friends_group_'+group_id)) {
                $('friends_group_'+group_id).innerHTML = title;
            }
            
            obj.timeOut = setTimeout(
                function () {
                    show(save);
                    var request = {
                        url: '/users/ajax_handle.do?action=rename_friend_group',
                        data: {
                            title: title,
                            group_id: group_id
                        },
                        onSuccess: function (res) {
                            hide(save);
                        }
                    };
                    AJAX(request);
                }, 700);
        }
    }
    
    this.showGroupsDropDown = function (event, user_id, link, sel_cat) {
        select = new DropDown(tr_module['MODULE_FRIENDS_MOVE_TO'], 'dropdown-std', null);
        
        var options = new Array();
        for(var i in friend_cats) {
            if (i != sel_cat) {
                var opt = new DropDownOption(friend_cats[i], i, function () {oThis.move_friend(user_id, this.v, link.parentNode.parentNode.parentNode.parentNode)});
                options.push(opt);
            }
        }
        
        select.setOptions(options);
        select.init();
        select.toggleMenu(event);
        
        link.parentNode.parentNode.insertBefore(select.get(), link.parentNode);
        hide(link.parentNode);
    }
    
    this.move_friend = function (user_id, group_id, link) {
        var request = {
            url: '/users/ajax_handle.do?action=move_friend',
            data: {
                group_id: group_id,
                friend_id: user_id
            },
            onSuccess: function (res) {
                fadeOut(link, 50, function () {link.parentNode.removeChild(link)});
            }
        };
        AJAX(request);
    }
    
    this.showRemoveFriend = function (user_id, usr, link) {
        this.popup_win && (this.popup_win.hide()) && (delete this.popup_win);
        
        if(!usr) usr = user_id;
        
        this.popup_win = new PopupWindow(tr['PROFILE_REMOVE_FRIEND_TITLE'], 'dialog-std');
        
        function buttons() {
            return [new Button(tr['PROFILE_REMOVE_FRIEND_BTN'], 'input-submit', function () {this.disabled=true; oThis.remove_friend(user_id, link, this)} ),
                    new Button(tr['PROFILE_CLOSE_BTN'], 'input-button', function () {oThis.popup_win.hide(); delete oThis.popup_win;} ) ];
        }
        function content() {
            var cont = document.createElement('div');
            
            cont.innerHTML = tr['PROFILE_REMOVE_FRIEND_DESC'].replace('{$user_name}', '<strong>'+usr+'</strong>');
            
            return cont;
        }
        
        var cont = document.body.firstChild.nodeType == 1 && document.body.firstChild || nextNode(document.body.firstChild);
        this.popup_win.display(cont, content, buttons, 'center');
    }
        
        
        this.remove_friend = function (user_id, link, btn) {
            var request = {
                url: '/ajax/friend_remove.do?k='+sid,
                data: {
                    friend_key: user_id
                },
                onSuccess: function (res) {
                    oThis.popup_win && oThis.popup_win.hide() && (delete oThis.popup_win);
                    
                    if(link) {
                        fadeOut(link, 50, function () {link.parentNode.removeChild(link)});
                    } else {
                        location.reload();
                    }
                },
                onFailure: function (res) {
                    oThis.popup_win.showError(res);
                    setTimeout(function () {btn.disabled = false;}, 1000);
                }
            };
            AJAX(request);
        }
    
    this.showFollow = function (usr, link) {
        this.follow(usr, link);
        return;
        
        this.popup_win && (this.popup_win.hide()) && (delete this.popup_win);
        
        if(!usr) usr = user_id;
        
        this.popup_win = new PopupWindow(tr['PROFILE_REMOVE_FRIEND_TITLE'], 'dialog-std');
        
        function buttons() {
            return [new Button('Follow User', 'input-submit', function () {this.disabled=true; oThis.follow(usr, link, this);} ),
                    new Button(tr['PROFILE_CLOSE_BTN'], 'input-button', function () {oThis.popup_win.hide(); delete oThis.popup_win;} ) ];
        }
        function content() {
            var cont = document.createElement('div');
            
            cont.innerHTML = 'Follow {$user_name}?'.replace('{$user_name}', '<strong>'+usr+'</strong>');
            
            return cont;
        }
        
        var cont = document.body.firstChild.nodeType == 1 && document.body.firstChild || nextNode(document.body.firstChild);
        this.popup_win.display(cont, content, buttons, 'center');
    }
        
        this.follow = function (usr, link, btn) {
            var request = {
                url: '/ajax/follow.do?k='+sid,
                data: { usr: usr },
                onSuccess: function (res) {
                    oThis.popup_win && oThis.popup_win.hide() && (delete oThis.popup_win);
                    
                    link.innerHTML = 'Unfollow';
                    link.onclick = function () { oThis.showUnfollow(usr, link); };
                    
                    if($('followers_cnt')) $('followers_cnt').innerHTML = parseInt($('followers_cnt').innerHTML)+1;
                },
                onFailure: function (res) {
                    oThis.popup_win.showError(res);
                    setTimeout(function () {btn.disabled = false;}, 1000);
                }
            };
            AJAX(request);
        }
    
    this.showUnfollow = function (usr, link) {
        this.unfollow(usr, link);
        return;
    
        this.popup_win && (this.popup_win.hide()) && (delete this.popup_win);
        
        if(!usr) usr = user_id;
        
        this.popup_win = new PopupWindow(tr['PROFILE_REMOVE_FRIEND_TITLE'], 'dialog-std');
        
        function buttons() {
            return [new Button('Unfollow User', 'input-submit', function () {this.disabled=true; oThis.unfollow(usr, link, this);} ),
                    new Button(tr['PROFILE_CLOSE_BTN'], 'input-button', function () {oThis.popup_win.hide(); delete oThis.popup_win;} ) ];
        }
        function content() {
            var cont = document.createElement('div');
            
            cont.innerHTML = 'Unfollow {$user_name}?'.replace('{$user_name}', '<strong>'+usr+'</strong>');
            
            return cont;
        }
        
        var cont = document.body.firstChild.nodeType == 1 && document.body.firstChild || nextNode(document.body.firstChild);
        this.popup_win.display(cont, content, buttons, 'center');
    }
        
        this.unfollow = function (usr, link, btn) {
            var request = {
                url: '/ajax/unfollow.do?k='+sid,
                data: { usr: usr },
                onSuccess: function (res) {
                    oThis.popup_win && oThis.popup_win.hide() && (delete oThis.popup_win);
                    
                    link.innerHTML = 'Follow';
                    link.onclick = function () { oThis.showFollow(usr, link); };
                    
                    if($('followers_cnt')) $('followers_cnt').innerHTML = parseInt($('followers_cnt').innerHTML)-1;
                },
                onFailure: function (res) {
                    oThis.popup_win.showError(res);
                    setTimeout(function () {btn.disabled = false;}, 1000);
                }
            };
            AJAX(request);
        }
    
    this.get_key = function(e, okFunc) {
        if (!e) e = window.event;
        
        var asc = !e.keyCode ? (!e.which ? e.charCode : e.which) : e.keyCode;
        
        if (asc != 17) {
            // натиснат е клавиш
            if (asc == 13 || (this.is_control_pressed && asc == 83)) {
                // CTRL + ENTER или CTRL+S
                this.is_control_pressed = false;
                if(okFunc) okFunc();
            }
        } else if (asc == 17) {
            this.is_control_pressed = 1;
        } else {
            this.is_control_pressed = false;
        }
        
        
    }
    
    this.check_key = function(e) {
        e = e || window.event;
        var asc = e.keyCode || !e.which || e.charCode;
        return asc;
    }
    
    this.checkAll = function (name) {
        var list = document.getElementsByName(name);
        
        for(var i=0; i<list.length; i++) {
            list[i].checked=true;
        }
    }
    
    this.uncheckAll = function (name) {
        var list = document.getElementsByName(name);
        
        for(var i=0; i<list.length; i++) {
            list[i].checked = false;
        }
    }
}