(function($) {




    if (!window.burocratos) { throw(_ERROR_NO_BUROCRATOS_OBJECT_FOUND); }
    if (window.burocratos.users) { return false; }




    window.burocratos.users = function(userId) {

        var
                _context = {
                        'userId'            : userId
                    ,   'contractorName'    : _$userLink(userId).html()
                }

            ,   _constructor = function() {  }

            ,   _self

            ;

        _constructor.prototype = _proto;
        _self = new _constructor();

        _self.context = function() {
            return _context;
        };

        return _self;

    };




    var _proto = {

            showContractorContextMenu: function(element) {
                _$contextMenu()
                    .unbind('click')
                    .click(function(e) {
                        if (!$(e.target).is('a')) { return false; }

                        if ($(e.target).closest('.contractor-remove').length) {
                            _removeContractor(this);
                        } else {
                            _applyContractor(this, $(e.target).closest('li').attr('id').substring(10));
                        }

                        _hideContractorContextMenu();
                    }.bind(this));

                if (_hiddenContractorContextMenu()) {
                    _showContractorContextMenu(_getContextMenuPosition(element));
                } else {
                    _moveContractorContextMenu(_getContextMenuPosition(element));
                }
            }

    };




    /*var
            _userId
        ;*/




    var
            _applyContractor = function(self, contractorId) {

                var oldValue = _$userLink(self.context().userId).html();

                _$userLink(self.context().userId).html(_$contractorLink(contractorId).html());

                _jsonContractor(
                        self.context().userId

                    ,   contractorId

                    ,   function() {
                            globalMessage('Привязка к контрагенту осуществлена успешно');
                        }

                    ,   function(message) {
                            globalMessage('Привязка к контрагенту не удалась. Причина: ' + message);

                            _$userLink(self.context().userId).html(oldValue);
                        }
                 ); // _jsonContractor call

            } // end of _applyContractor

        ,   _removeContractor = function(self, contractorId) {

                var oldValue = _$userLink(self.context().userId).html();

                _$userLink(self.context().userId).html('прикрепить');

                _jsonContractor(
                        self.context().userId

                    ,   -1

                    ,   function() {
                            globalMessage('Отмена привязки пользователя к контрагенту произведена успешно');
                        }

                    ,   function(message) {
                            globalMessage('Отмена привязки пользователя к контрагенту не удалась. Причина: ' + message);

                            _$userLink(self.context().userId).html(oldValue);
                        }
                 ); // _jsonContractor call

            }

        ,   _jsonContractor = function(userId, contractorId, success, error) {



                $.getJSON(
                        _CHANGE_CONTRACTOR_URL

                    ,   {
                                'userId'        : userId
                            ,   'contractorId'  : contractorId
                        }

                    ,   function(response) {
                            if (response && response.status) {
                                success();
                            } else {
                                error(undefined);
                            }
                        }
                );

            }

        ;




    var
            _ERROR_NO_BUROCRATOS_OBJECT_FOUND       = 'global object [burocratos] not found'

        ,   _STATE_CONTRACTOR_CONTEXT_MENU_HIDDEN   = 100

        ,   _STATE_CONTRACTOR_CONTEXT_MENU_HIDING   = 101

        ,   _STATE_CONTRACTOR_CONTEXT_MENU_SHOWING  = 102

        ,   _STATE_CONTRACTOR_CONTEXT_MENU_SHOWN    = 103

        ,   _KEY_CONTRACTOR_CONTEXT_MENU_STATE      = 'contractor-context-menu-state'

        ,   _CONTEXT_MENU_SHOW_DELAY                = 500

        ,   _CHANGE_CONTRACTOR_URL                  = '?scenario=user.contractor.change'

        ,   _CONTEXT_MENU_VERTICAL_OFFSET           = 20

        ;




    var
            _$contextMenu = function() {
                return $('#contractorListContextMenu');
            }

        ,   _$userLink = function(userId) {
                return $('a#userLink' + userId);
            }

        ,   _$contractorLink = function(contractorId) {
                return $('li#contractor' + contractorId).find('a');
            }

        ;





    var
            _shownContractorContextMenu = function() {
                return _STATE_CONTRACTOR_CONTEXT_MENU_SHOWN == _contractorMenuState();
            }

        ,   _hiddenContractorContextMenu = function() {
                return  _STATE_CONTRACTOR_CONTEXT_MENU_HIDDEN == _contractorMenuState()
                    ||  !_contractorMenuState();
            }

        ,   _showContractorContextMenu = function(absolutePoint) {
                _contractorMenuState(_STATE_CONTRACTOR_CONTEXT_MENU_SHOWING);
                _moveContractorContextMenu(absolutePoint);
                _$contextMenu()
                    .css({
                            'display'   : 'block'
                        ,   'opacity'   : 0
                    })
                    .animate(
                            { 'opacity' : 1 }
                        ,   _CONTEXT_MENU_SHOW_DELAY
                        ,   function() {
                                _contractorMenuState(_STATE_CONTRACTOR_CONTEXT_MENU_SHOWN);
                            }
                    );
            }

        ,   _moveContractorContextMenu = function(absolutePoint) {
                var $node = _$contextMenu().parent();
                while (document != $node.get(0) && 'absolute' != $node.css('position') && 'relative' != $node.css('position')) {
                    $node = $node.parent();
                }
                absolutePoint.left -= $node.offset().left;
                absolutePoint.top -= $node.offset().top;

                _$contextMenu()
                    .css({
                            'left'  : absolutePoint.left + 'px'
                        ,   'top'   : absolutePoint.top + 'px'
                    });
            }

        ,   _hideContractorContextMenu = function() {
                _contractorMenuState(_STATE_CONTRACTOR_CONTEXT_MENU_HIDING);
                _$contextMenu()
                    .animate(
                            { 'opacity' : 0 }
                        ,   _CONTEXT_MENU_SHOW_DELAY
                        ,   function() {
                                _$contextMenu().css({ 'display'   : 'none' });
                                _contractorMenuState(_STATE_CONTRACTOR_CONTEXT_MENU_HIDDEN);
                            }
                    );
            }

        ,   _contractorMenuState = function(state) {
                if ('undefined' != typeof state) {
                    _$contextMenu().data(_KEY_CONTRACTOR_CONTEXT_MENU_STATE, state)
                } else {
                    return _$contextMenu().data(_KEY_CONTRACTOR_CONTEXT_MENU_STATE);
                }
            }

        ,   _getAbsolutePoint = function(event) {
                return {
                        'left'  : event.pageX
                    ,   'top'   : event.pageY
                };
            }

        ,   _getContextMenuPosition = function(element) {

                var point = $(element).offset();
                point.top = parseInt(point.top) + _CONTEXT_MENU_VERTICAL_OFFSET;

                return point;

            }

        ;




    $(document).click(function(e) {
        if (_$contextMenu().find(e.target).length) { return true; }

        if (_shownContractorContextMenu()) {
            _hideContractorContextMenu();
        }

        return true;
    });




})(jQuery);
