Phx.namespace('Phx.Application.Modules.WriteMessage', new function()
{
    var autosuggest             = null;
    var $scope                  = null;
    var _this                   = this;
    var MAX_COUNT_OF_RECIPIENTS = 10;
    var _currentDataList        = [];

    var MAX_COUNT_OF_FRIENDLISTS = 1;
    var friendslistsData        = {};
    var countOfSelectedFriendslists = 0;
    var FRIENDSLISTS_PREFIX     = 'friendslists_';

    /**
     * min size of searchfield
     *
     * @var {Number}
     */
    MIN_SEARCHFIELD_SIZE = 120;

    this.init = function(config)
    {
        if (typeof Phx.Application.Autosuggest === 'undefined') {
            return;
        }

        if (typeof config === 'object') {
            MAX_COUNT_OF_RECIPIENTS = (typeof config['maxFriendsCount'] == 'number') ? config['maxFriendsCount'] : MAX_COUNT_OF_RECIPIENTS;
            MAX_COUNT_OF_FRIENDLISTS = (typeof config['maxFriendsListsCount'] == 'number') ? config['maxFriendsListsCount'] : MAX_COUNT_OF_FRIENDLISTS;
        }
        
        $scope = $('#Messages_WriteForm');

        if (!$scope.length) {
            return;
        }

        var $searchfield = $('#Messages_searchfield', $scope);
        if($searchfield.length === 0) {
        	return;
        }
        
        var $resultbox   = $('#resultbox', $scope);

        eval('var data = ' + $('#friendList', $scope).val() + ';');
        eval('friendslistsData = ' + $('#friendslists', $scope).val() + ';');

        var $config = {
            data: data
        };

        autosuggest = new Phx.Application.Autosuggest($searchfield, $resultbox, $config);
        autosuggest.getCounterAndMatchesHook = Phx.Util.createDelegate(this.getCounterAndMatches, this);
        autosuggest.matchesHook              = Phx.Util.createDelegate(this.handleMatches, this);
        autosuggest.noMatchesHook            = Phx.Util.createDelegate(this.handleNoMatches, this);
        autosuggest.spaceKeyListenerHook     = Phx.Util.createDelegate(this.spaceKeyListener, this);
        autosuggest.tabKeyListenerHook       = Phx.Util.createDelegate(this.tabKeyListener, this);
        autosuggest.returnKeyListenerHook    = Phx.Util.createDelegate(this.returnKeyListener, this);
        autosuggest.backspaceKeyListenerHook = Phx.Util.createDelegate(this.backspaceKeyListener, this);
        autosuggest.escapeKeyListenerHook    = Phx.Util.createDelegate(this.escapeKeyListener, this);
        autosuggest.multiKeyListenerHook     = Phx.Util.createDelegate(this.multiKeyListener, this);
        //autosuggest.setResultboxPositionHook = Phx.Util.createDelegate(this.setResultboxPosition, this);
        autosuggest.onClickResultvalueHook   = Phx.Util.createDelegate(this.onClickResultvalue, this);
        autosuggest.onBlurHandlerHook        = Phx.Util.createDelegate(this.onBlurHandler, this);

        var $_autocompleteContainer = $('#autocompleteContainer', $scope);

        $_autocompleteContainer.unbind('click.focusSearchfield').bind('click.focusSearchfield', function() {
            autosuggest.$searchfield.focus();
        });

        var $_nameboxes = $('.namebox', $scope);
        var countOfRecipients = $_nameboxes.length;

        if (countOfRecipients) {
            this.initPreselectedRecipients($_nameboxes);
        }

        if (!$('#Messages_message', $scope).val() && !$('#Messages_subject', $scope).val()) {
            if (autosuggest.$searchfield) {
                // set focus again
                autosuggest.$searchfield.focus();
            }
        }

        autosuggest.setResultboxPosition();
    };

    this.initPreselectedRecipients = function($nameboxes)
    {
        $.each($nameboxes, function() {
            var _$friendlist = $('.friendslists', $(this));
            if (_$friendlist.length) {
                var friendslistsId = _$friendlist.val();

                $('#del_'+ FRIENDSLISTS_PREFIX + friendslistsId).unbind('click.deleteRecipient').bind('click.deleteRecipient', function() {
                    $(this).parents('span').remove();
                    _this.removeRecipient(FRIENDSLISTS_PREFIX + friendslistsId);
                });

                ++countOfSelectedFriendslists;
            } else {
                var recipientIds  = $('.recipientIds', $(this)).val();
                var recipientName = $('.recipientname', $(this)).html();

                _currentDataList[recipientIds] = recipientName;

                _this.displayMultiRecipientInfo();

                $('#del_'+ recipientIds, $(this)).unbind('click.deleteRecipient').bind('click.deleteRecipient', function() {
                    $(this).parents('span').remove();
                    _this.removeRecipient(recipientIds);
                });
            }

            _this.toggleHistoryLink();
        });
    };

    this.onBlurHandler = function()
    {
        var $_dl = $('dl', autosuggest.$resultbox);
        var countOfResults = $_dl.length;

        if (countOfResults === 1) {
            $_dl.parent('div').removeClass('unselected selected').addClass('selected');
            this.addRecipientToList();
        }
    };

    this.spaceKeyListener = function()
    {
        this.addRecipientToList();
    };

    this.tabKeyListener = function()
    {
        this.addRecipientToList();
    };

    this.returnKeyListener = function()
    {
        this.addRecipientToList();
    };

    this.backspaceKeyListener = function(value)
    {
        var countOfRecipients = $('.namebox', $scope).length;

        if (value !== '' || countOfRecipients <= 0) {
            return;
        }

        var arrayLength = 0;
        for (var key in _currentDataList) {
            arrayLength++;
        }

        var counter = 0;
        for (var newKey in _currentDataList) {
            counter++;
            if (0 === arrayLength || counter === arrayLength && !$('.friendslissts', $_lastRecipient).length) {
                delete _currentDataList[newKey];
            }
        }

        var $_lastRecipient = $('.namebox').get((countOfRecipients-1));
        $($_lastRecipient).remove();

        _currentDataList.pop();

        if ($('.friendslists', $_lastRecipient).length) {
            var _friendslistsId = $('.friendslists', $_lastRecipient).val();
            this.removeRecipient(FRIENDSLISTS_PREFIX + _friendslistsId);
        } else {
            var _recipientId = $('.recipientIds', $_lastRecipient).val();
            this.removeRecipient(_recipientId);
        }

    };

    this.escapeKeyListener = function()
    {
        this.removeErrors();
        autosuggest.closeResultbox();
    };

    this.multiKeyListener = function()
    {
        var $_selectedValue = $('.selected', autosuggest.$resultbox);

        if (!$_selectedValue.length) {
            this.onBlurHandler();

            return;
        }

        this.addRecipientToList();
    };

    this.handleMatches = function()
    {
        this.removeErrors();
    };

    this.removeErrors = function()
    {
        autosuggest.$searchfield.removeClass('invalidNested');

        var $_autocompleteContainer = $('#autocompleteContainer', $scope);
        $_autocompleteContainer.removeClass('invalid');
    };

    this.removeRecipient = function(_recipientId)
    {
        if (_recipientId.indexOf(FRIENDSLISTS_PREFIX) !== -1) {
            --countOfSelectedFriendslists;
        } else {
            // make recipient in resultbox available
            delete _currentDataList[_recipientId];
        }
        this.toggleHistoryLink();

        autosuggest.setResultboxPosition();

        this.displayMultiRecipientInfo();

        this.displayMaxCountOfRecipients();
    };

    this.addRecipientToList = function() {

        if (!autosuggest._currentSelectedValue === -1) {
            return;
        }

        autosuggest._currentSelectedValue = -1;

        var $_selectedValue = $('.selected', autosuggest.$resultbox);

        if (!$_selectedValue.length) {
            return;
        }

        // hide resultbox
        autosuggest.closeResultbox();

        // FRIENDSLISTS
        if ($_selectedValue.attr('id').indexOf(FRIENDSLISTS_PREFIX) !== -1) {
            var friendslistsId   = $_selectedValue.attr('id').substr(FRIENDSLISTS_PREFIX.length);
            var friendslistsName = $('dt', $_selectedValue).text();

            autosuggest.$searchfield.before('<span class="namebox friendslist"><span class="recipientname">' + autosuggest.xssSecure(friendslistsName) + '</span> <a id="del_' + FRIENDSLISTS_PREFIX + friendslistsId + '" class="deleteMe">&nbsp;</a>' + '<input type="hidden" class="friendslists" name="friendlistIds[]" value="' + friendslistsId + '"></input></span>');

            $('#del_'+ FRIENDSLISTS_PREFIX + friendslistsId).unbind('click.deleteRecipient').bind('click.deleteRecipient', function() {
                $(this).parents('span').remove();
                _this.removeRecipient(FRIENDSLISTS_PREFIX + friendslistsId);
            });

            ++countOfSelectedFriendslists;
        } else {

            if (this.displayMaxCountOfRecipients()) {
                return;
            }

            var _recipientId    = $_selectedValue.attr('id');
            var _recipientName  = $('dt', $_selectedValue).text();

            // insert name in front of searchfield
            autosuggest.$searchfield.before('<span class="namebox"><span class="recipientname">' + autosuggest.xssSecure(_recipientName) + '</span> <a id="del_' + _recipientId + '" class="deleteMe">&nbsp;</a>' + '<input type="hidden" class="recipientIds" name="recipientIds[]" value="' + _recipientId + '"></input></span>');

            // set recipient to the list of already selected values
            _currentDataList[_recipientId] = _recipientName;


            $('#del_'+ _recipientId).unbind('click.deleteRecipient').bind('click.deleteRecipient', function() {
                $(this).parents('span').remove();
                _this.removeRecipient(_recipientId);
            });

        }
        this.toggleHistoryLink();

        autosuggest.setResultboxPosition();

        autosuggest.closeResultbox();

        autosuggest.clearSearchfield();

        if (!autosuggest.$searchfield.val()) {
            // set focus again
            autosuggest.$searchfield.focus();
        }

        this.displayMultiRecipientInfo();
    };

    this.toggleHistoryLink = function()
    {
        var countOfRecipients = $('.namebox', $scope).length;
        var $_historyContent = $('#historyContent', $scope);
        var $_historyLink    = $('#historyLink', $scope);

        // check if a friendlist is in
        if ($('.friendslists', $('.namebox', $scope)).length) {
            $_historyLink.hide();
            $_historyContent.html('');
            return;
        }


        // clear history data
        $_historyContent.html('');
        $_historyLink.removeClass('opened');

        // display historylink if one recipient is preselected
        if (countOfRecipients === 1) {
            var idsOfRecipient = $('.recipientIds', $('.namebox')).val();
            var $_idsForHistory  = $('#recipientIdForHistory');

            $_idsForHistory.val(idsOfRecipient);

            if (typeof Phx.Application.Modules.Messages !== 'undefined') {
                Phx.Application.Modules.Messages.bindHistory();
                $_historyLink.show();
            }

        } else {
            $_historyLink.hide();
        }
    };

    this.getCounterAndMatches = function(value, $dataStack)
    {
        var matches = '';
        var counter = 0;

        // insert a matched name
        $.each(friendslistsData, function(key, valueSet) {
            if (valueSet.name) {
                if (valueSet.name.toLowerCase().indexOf(value.toLowerCase()) !== -1 && MAX_COUNT_OF_FRIENDLISTS > countOfSelectedFriendslists) {
                    matches += '<div style="z-index:9999" class="unselected" id="friendslists_' + key + '">';
                    matches += '<dl class="friendslist"><dt style="margin-top: 10px;">' + autosuggest.getMarkedMatch(value, valueSet.name) + ' (' + valueSet.members + ')' + '</dt>';
                    matches += '<dd class="user-image" style="background-image: url(' + valueSet.imagePath + '); width: 35px; height: 35px"></dd>';
                    matches += '</dl></div>';

                    ++counter;
                }
            }
        });

        $.each($dataStack, function(key, valueSet) {
            if (valueSet.name) {
                if (valueSet.name.toLowerCase().indexOf(value.toLowerCase()) !== -1 && !_currentDataList[key] && counter <= 20) {
                    matches += '<div style="z-index:9999" class="unselected" id="' + key + '">';
                    matches += '<dl><dt>' + autosuggest.getMarkedMatch(value, valueSet.name) + '</dt>';
                    matches += '<dd class="user-image" style="background-image: url(' + valueSet.imagePath + '); width: 35px; height: 35px"></dd>';
                    matches += '<dd class="user-uniname">' + valueSet.uniName + '</dd></dl></div>';

                    ++counter;
                }
            }
        });

        var $data = {
            counter : counter,
            matches : matches
        };

        return $data;
    };

    this.onClickResultvalue = function($clickedObject)
    {
        this.addRecipientToList();
    };

    this.handleNoMatches = function(value)
    {
        var $_autocompleteContainer = $('#autocompleteContainer', $scope);

        if (value !== '') {
            $_autocompleteContainer.addClass('invalid');
            autosuggest.$searchfield.addClass('invalidNested');
            autosuggest.$resultbox.html('<div class="noMatches">' + i18n.getText('error_recipient_not_found', value) + '</div>');
        } else {
            $_autocompleteContainer.removeClass('invalid');
            autosuggest.$searchfield.removeClass('invalidNested');
        }
    };

    this.displayMultiRecipientInfo = function()
    {

        var countOfRecipients = $('.namebox', $scope).length;
        var $_multiRecipientId = $('#multirecipientInfo');

        if (countOfRecipients <= 1) {
            if ($_multiRecipientId.length) {
                $_multiRecipientId.remove();
            }
            return;
        }

        if ($_multiRecipientId.length) {
            return;
        }

        var $_autocompleteContainer = $('#autocompleteContainer', $scope);
        $_autocompleteContainer.parent('fieldset').after('<div id="multirecipientInfo" class="hint">' + i18n.getText('message_multiRecipients') + '</div>');
    };

    this.displayMaxCountOfRecipients = function()
    {
        var $_recipientError = $('#recipientError', $scope);
        var _nameboxesLength = $('.namebox', $scope).length;

        // check if a friendlist is in
        if ($('.friendslists', $('.namebox', $scope)).length) {
            --_nameboxesLength;
        }

        // cancel if ten recipients obtained
        if (_nameboxesLength === MAX_COUNT_OF_RECIPIENTS) {
            $_recipientError.html(i18n.getText('message_maxCountOfRecipients', MAX_COUNT_OF_RECIPIENTS));
            $_recipientError.show();
            return true;
        } else {
            // not beautiful but a must have
            if ($_recipientError.html() === i18n.getText('message_maxCountOfRecipients', MAX_COUNT_OF_RECIPIENTS)) {
                $_recipientError.html('');
                $_recipientError.hide();
            }
            return false;
        }
    };

    /**
     * set position of resultbox
     */
    this.setResultboxPosition = function()
    {
        var searchfieldHeight  = autosuggest.$searchfield.height();
        var searchfieldWidth   = autosuggest.$searchfield.width();

        autosuggest.$searchfield.css('width', '100%');
        autosuggest.$searchfield.css('float', 'left');
        this.calculatePosition();

        var offset = autosuggest.$searchfield.offset();
        var _parentOffset = 0;
        var _parentHeight = 0;
        var _parentMargin = 0;

        if ($('.dialog-wrapper').length) {
            var $_phxDialog = $('.dialog-wrapper');
            _parentOffset = $_phxDialog.offset();
            _parentHeight = _parentOffset.top;
            _parentMargin = $.browser.msie ? parseInt($_phxDialog.css('margin-left')) : 0;
        } else {
            _parentOffset = $('#Grid-Wrapper').offset();
            _parentHeight = _parentOffset.top;
        }

        var searchfieldLeft = (offset.left - _parentOffset.left - _parentMargin);

        autosuggest.$resultbox.css('position', 'absolute');
        autosuggest.$resultbox.css('left', searchfieldLeft);
        autosuggest.$resultbox.css('top', (offset.top + searchfieldHeight - _parentHeight + 5));
    };

    this.calculatePosition = function()
    {
        var $_container            = $('#autocompleteContainer');
        var _containerPaddingLeft  = $_container.css('padding-left') ? parseInt($_container.css('padding-left')) : 0;
        var _containerPaddingRight = $_container.css('padding-right') ? parseInt($_container.css('padding-right')) : 0;

        var _realContainerWidth = (parseInt($_container.width()) - _containerPaddingLeft - _containerPaddingRight);

        var _searchfieldMarginLeft  = autosuggest.$searchfield.css('margin-left') ? parseInt(autosuggest.$searchfield.css('margin-left')) : 0;
        var _searchfieldMarginRight = autosuggest.$searchfield.css('margin-right') ? parseInt(autosuggest.$searchfield.css('margin-right')) : 0;

        var _currentWidth = 0;
        $.each($('.namebox'),function() {
            var _nameboxWidth       = parseInt($(this).width());
            var _nameboxMarginLeft  = $(this).css('margin-left') ? parseInt($(this).css('margin-left')) : 0;
            var _nameboxMarginRight = $(this).css('margin-right') ? parseInt($(this).css('margin-right')) : 0;

            var _realNameboxWidth = (_nameboxWidth + _nameboxMarginLeft + _nameboxMarginRight + _containerPaddingLeft + _containerPaddingRight);
            _currentWidth += _realNameboxWidth;

            if (_currentWidth > _realContainerWidth) {
                _currentWidth = _realNameboxWidth;
            }

            var _rest = (_realContainerWidth - _currentWidth);
            if (_rest >= MIN_SEARCHFIELD_SIZE) {
                autosuggest.$searchfield.css('width', _rest + 'px');
            } else {
                autosuggest.$searchfield.css('width', '100%');
            }
        });
    };

    this.resetFriendList = function()
    {
        _currentDataList = [];
        countOfSelectedFriendslists = 0;

    };

    this.showReplyMessageDialog = function(response, subject, callback) {

        // check for errors
        if (typeof response.module.errors == 'object') {

            var dialog = Phx.UI.Dialog.ButtonDialog(i18n.getText('error_head'), {
                message: response.module.errors.messages.Messages,
                buttons : [
                        new Phx.UI.Button.Submit(i18n.getText('close'), false)
                        ],
                events: {
                    onButtonClicked: function (result)
                    {
                        if (typeof callback == 'function')
                            callback(false);
                        
                        return;
                    }
                }
            });

            dialog.show();
            return;
        }

        // otherwise render the messaging dialog
        var dialog = Phx.UI.Dialog.HTML(i18n.getText('message_write'), {
            message : response.module.data.html
        });

        dialog.show();

        // init emoticons if posible
        if (typeof Phx.Application.Modules.MessagesEmoticons !== 'undefined') {
            Phx.Application.Modules.MessagesEmoticons.init();
        }

        var $_form = $('#Messages_WriteForm');

        var $_backLink = $('#backLink', $_form);
        $_backLink.attr('href', 'javascript:;');

        // truncate only if subject is not empty
        var truncatedSubject = subject.length == 0 ? '' : subject.substring(0, 63) + '...';
        
        $('#Messages_subject' ,$(dialog.getDomSelector())).val(truncatedSubject);

        // close dialog
        $_backLink.unbind('click.closeDialog').bind('click.closeDialog', function() {
            dialog.close();
            callback(false);
        });

        _replyMessageRequest($_form, dialog, callback);
    }


    /**
     * send request and handle response if user sends a replymessage
     *
     * @param {Object} $_form
     * @param {Object} dialog
     */
    var _replyMessageRequest = function ($_form, dialog, callback) {
        $_form.submit(Phx.Application.Modules.Forms.bindAjaxForms)
            .bind('formSuccess', function(event, data) {
                // IVW calling
                if ('function' == typeof ResetPixelImages) {
                    ResetPixelImages();
                }

                dialog.close();
                
                if (typeof callback == 'function')
                    callback(true);
                
                var successDialog = Phx.UI.Dialog.Alert(i18n.getText('message_sent_head'), {
                    message : i18n.getText('message_sent_content'),
                    events: {
                        onButtonClicked: function(result)
                        {
                        }
                    }
                });
                $().trigger('OmnitureTracking', {name: 'messageSent', location: 'replyMessage'});

                successDialog.show();
            });
    };



}());
