chatHead = function($environment) {
    this.buble_size = 60; // size bubble
    this.is_drag = false; // lock drag
    this.is_expand = false; // lock drag
    this.limit_in_bubble = parseInt(Math.min($(window).height(), $(window).width()) / (this.buble_size + 4));
    this.scope = {};
    this.compile = {};
    this.environment = $environment;
    this.last_in_bubbles = [];
    this.obj_after_parse = {};
    this.user_message = [];
    this.group_message = [];
    var location_page = (window.location.pathname).substring((window.location.pathname).lastIndexOf('/') + 1);
    this.lock_module = (location_page == 'chat.html') ? true : false;
    this.show_keyboard = false;
    this.keyboard_height = 0;
    this.hanlder_group = -1;
    this.shakeEvent = null;
};
chatHead.prototype = {
    initial: function($main_container, $chat_container, $drop_area, $callback) {
        var _self = this;
        this.selector = {
            main_container: $main_container,
            chat_container: $chat_container,
            drop_area: $drop_area
        };
        return $callback();
    },
    initShake: function() {
        var _self = this;
        if (_self.shakeEvent != null) {
            return;
        }
        _self.shakeEvent = new Shake({
            threshold: 15
        });
        //listen to shake event
        _self.shakeEvent.reset();
        _self.shakeEvent.start();
        // window.addEventListener('shake', function() {
        //     _self.shakeEvent.stop();
        //     _self.eventShake();
        // }, false);
        //check if shake is supported or not.
        if (!("ondevicemotion" in window)) {
            alert("Not Supported");
        }
    },
    eventShake: function() {
        var _self = this;
        angular.element('.bubble').removeClass('haschoose');
        angular.element('.group-bubble-chat > div.bubble').triggerHandler('click');
        _self.environment('.out-group-bubble').siblings('.chat').addClass('clicktoggle');
    },
    initDraggable: function($selector, $status = false) {
        var _self = this;
        $selector.draggable({
            revertDuration: 200,
            revert: function($event) {
                if ($status) {
                    return true;
                } else if (_self.hanlder_group != 2) {
                    var uiDraggable = _self.environment(this).data("uiDraggable");
                    if (uiDraggable.position.left > _self.environment(window).width() / 2) {
                        uiDraggable.originalPosition.left = _self.environment(window).width() - _self.buble_size;
                    } else {
                        uiDraggable.originalPosition.left = 0;
                    }
                    uiDraggable.originalPosition.top = uiDraggable.position.top > _self.environment(window).height() - _self.buble_size ? //
                    _self.environment(window).height() - _self.buble_size : uiDraggable.position.top < 0 ? 0 : uiDraggable.position.top;
                    return !$event;
                } else {
                    return 'valid';
                }
            },
            stop: function($event, $ui) {
                _self.environment(this).closest(_self.selector.main_container).find(_self.selector.drop_area).removeClass('show');
                _self.is_drag = false;
                if (_self.environment($ui.helper[0]).hasClass('group-bubble-chat') && _self.last_in_bubbles.length == 0 && _self.hanlder_group == 0) {
                    _self.environment('.group-bubble-chat > div.bubble').addClass('haschoose');
                }
                if (_self.hanlder_group != -1) {
                    setTimeout(function() {
                        _self.is_expand ? angular.element('.group-bubble-chat > div.bubble').triggerHandler('click') : '';
                    }, 0);
                }
                _self.hanlder_group = -1;
            },
            drag: function($event, $ui) {
                _self.is_drag = true;
                _self.environment(this).closest(_self.selector.main_container).find(_self.selector.drop_area).addClass('show');
            }
        });
    },
    draggableIsExpand: function($status = false) {
        var _self = this;
        _self.environment(_self.selector.chat_container).find('.group-bubble').find('.bubble-sub').each(function($index) {
            if (_self.environment(this).hasClass('ui-draggable')) {
                _self.environment(this).draggable('destroy');
            }
            if ($status) {
                _self.initDraggable(_self.environment(this), true);
            }
        });
    },
    messageToExpand: function($arguments1, $arguments2) {
        var _self = this;
        var _index = _.findLastIndex($arguments2[1], {
            room_id: $arguments2[1].room_id,
            id: $arguments2[1].id,
        });
        if(parseInt($arguments2[1].room_id) > 0){
            _index = _.findLastIndex($arguments2[1], {
                room_id: $arguments2[1].room_id
            });
        }
        function callBackItems($selector, callback) {
            _interval = setInterval(function() {
                return callback($selector);
            }, 0);
        }
        callBackItems(_self.environment('.in-window'), function(arg) {
            if (_self.environment('.in-window').length == $arguments1.length) {
                clearInterval(_interval);
                _self.scope.$apply(function(val) {
                    var _reverse = _self.environment('.in-window');
                    _reverse.each(function($index) {
                        var _item = JSON.parse(_self.environment(this).attr('mappitem'));
                        var __index = _.findLastIndex(_item, {
                            room_id: _item.room_id,
                            id: _item.id,
                        });
                        if(parseInt(_item.room_id) != 0){
                            __index = _.findLastIndex(_item, {
                                room_id: _item.room_id
                            });
                        }
                        if (_index == __index) {
                            _self.onExpand(_self.environment(this), $arguments2[1], false, function($arguments) {
                                //
                            })
                        }
                    });
                });
            }
        });
    },
    onExpand: function($selector, $item = null, $hanlder, $callback) {
        var _self = this;
        var __self = _self.environment($selector).closest(_self.selector.chat_container);
        if ($hanlder) {
            __self.find('.bubble').removeClass('haschoose');
            __self.find('.bubble-sub').removeClass('z-index9');
            _self.environment($selector).closest('.group-bubble').find('.group-bubble-chat').css('display', 'block');
            _self.environment($selector).addClass('haschoose');
            if ($item) {
                _self.environment($selector).closest('.out-group-bubble').siblings('.chat').addClass('clicktoggle');
                _self.environment($selector).closest('.out-group-bubble').siblings('.chat').find('.chat-main-user').removeClass('none').siblings('.chat-main-admin').addClass('none');
            }
        }
        __self.find('.group-bubble').addClass('position_unset').css('width', (_self.last_in_bubbles.length + 1) * _self.buble_size);
        __self.find('.group-bubble').draggable("disable");
        __self.find('.bubble-sub').addClass('position_unset').addClass('pdLR5');
        _self.environment($selector).closest('.bubble-sub').addClass('z-index9');
        _self.draggableIsExpand(_self.is_expand = true);
        _.each(_self.last_in_bubbles, function($_item, $index) {
            _.extend($_item, {
                on_active: true
            });
        });
        return $callback($item);
    },
    overLapChat: function($keyboardHeight = 0) {
        var _self = this;
        if (_self.is_expand) {
            _self.environment(_self.selector.chat_container).addClass('chat_head_expand');
            if (_self.show_keyboard) {
                var _str_style = 'height: ' + ((_self.environment(window).height() - _self.keyboard_height) * 100) / _self.environment(window).height() + 'vh !important;';
                _str_style = _str_style + 'width: 100vw;';
                angular.element('.chat_container').attr('style', _str_style);
            } else {
                _self.environment(_self.selector.chat_container).animate({
                    height: '100vh',
                    width: '100vw'
                }, 0, function() {
                    _self.environment(_self.selector.chat_container).addClass('chat_head_expand');
                });
            }
        } else {
            _self.environment(_self.selector.chat_container).removeClass('chat_head_expand');
            _self.environment(_self.selector.chat_container).animate({
                height: 0,
                width: 0
            }, 0, function() {
                _self.environment(_self.selector.chat_container).removeClass('chat_head_expand');
            });
        }
    },
    eventlistener: function() {
        var _self = this;
        /*angular*/
        _self.scope.onHold = function(){
            setTimeout(function() {
                _self.eventShake();
            }, 0);
        };
        _self.scope.onContacts = function($item) {
            Boolean($item.msg) ? '' : $item.msg = {
                counter: 0,
                room_id: 0
            };
            if ($item.msg.room_id && !Boolean($item.msg.room_id)){
                _.extend($item.msg, {
                    user_id: $item.id
                })
            }
            _self.pullMessage(angular, $item, $item.msg, 1, function($arguments1, $arguments2) {
                _self.scope.objChatHead(_self.scope);
                _self.scope.obj_chat_head.bubbleArr = _self.last_in_bubbles;
                _self.messageToExpand($arguments1, $arguments2);
            });
        };
        _self.scope.onChatBubble = function($event, $item = null) {
            if (_self.is_drag) {
                _self.overLapChat();
                return;
            }
            var _selector = _self.environment($event.currentTarget);
            var __self = _selector.closest(_self.selector.chat_container);
            if (_selector.hasClass('haschoose')) {
                /*collapse*/
                _self.environment('.group-bubble-set-pos').addClass('group-bubble-pos-fix-i');
                __self.find('.group-bubble').removeClass('position_unset').css('width', _self.buble_size);
                __self.find('.bubble-sub').removeClass('position_unset').removeClass('pdLR5').attr('style', '');
                _selector.closest('.out-group-bubble').siblings('.chat').removeClass('clicktoggle');
                _selector.closest('.group-bubble').find('.group-bubble-chat').css('display', 'none');
                _selector.removeClass('haschoose');
                __self.find('.group-bubble').draggable("enable");
                _self.draggableIsExpand(_self.is_expand = false);
                _.each(_self.last_in_bubbles, function($_item, $index) {
                    _.extend($_item, {
                        on_active: false
                    });
                });
                if ($item) {
                    $item.on_active = true;
                } else if (_self.last_in_bubbles.length > 0) {
                    _self.last_in_bubbles[_self.last_in_bubbles.length - 1].on_active = false;
                }
                if(_selector.hasClass('is-group-contant')){
                    _self.shakeEvent.reset();
                    _self.shakeEvent.start();
                }
            } else {
                /*expand*/
                _self.onExpand(_selector, $item, true, function($arguments) {
                    _self.environment('.group-bubble-set-pos').removeClass('group-bubble-pos-fix-i');
                    _self.environment('.group-bubble-set-pos').attr('style', String(_self.environment('.group-bubble-set-pos').attr('style')).replace('position: relative;', ''));
                    if ($item != null) {
                        $arguments.room_id != 0 ? _self.scope.getNameChat($arguments.room_id, true) : _self.scope.getNameChat($arguments.id, false);
                        var _index = _.findLastIndex(_self.last_in_bubbles, {
                            room_id: $item.room_id,
                            id: $item.id,
                        });
                        if(parseInt($item.room_id) > 0){
                            _index = _.findLastIndex(_self.last_in_bubbles, {
                                room_id: $item.room_id,
                            });
                        }
                        if (_index != -1) {
                            _self.last_in_bubbles[_index].counter = 0;
                            _self.scope.obj_chat_head.bubbleArr[_index].counter = 0;
                        }
                    }
                });
            }
            _self.overLapChat();
        };
        /*on group bubble click*/
        _self.environment(_self.selector.chat_container).unbind('click');
        _self.environment(_self.selector.chat_container).on('click', 'div.group-bubble-chat', function() {
            _self.environment(this).closest('.out-group-bubble').siblings('.chat').find('.chat-main-admin').removeClass('none').siblings('.chat-main-user').addClass('none');
        });
        /*drop exits to remove item*/
        _self.environment(_self.selector.drop_area).find('.drop-area__item').unbind('droppable');
        _self.environment(_self.selector.drop_area).find('.drop-area__item').droppable({
            drop: function($event, $ui) {
                if (_self.environment($ui.helper[0]).find('.bubble').attr('mappitem') && _self.is_expand) {
                    var _item = JSON.parse(_self.environment($ui.helper[0]).find('.bubble').attr('mappitem'));
                    var _index = _.findLastIndex(_self.last_in_bubbles, {
                        room_id: _item.room_id,
                        id: _item.id,
                    });
                    if(parseInt(_item.room_id) > 0){
                        _index = _.findLastIndex(_self.last_in_bubbles, {
                            room_id: _item.room_id
                        });
                    }
                    if (_index != -1) {
                        _self.environment($ui.helper[0]).hide();
                        _self.last_in_bubbles.splice(_index, 1);
                        _self.scope.bubbleArr = _self.last_in_bubbles;
                        if (_self.environment($ui.helper[0]).find('.bubble').hasClass('haschoose')) {
                            _self.environment('div.group-bubble-chat').trigger('click');
                            _self.hanlder_group = 1;
                        }
                    };
                } else {
                    // close all
                    _self.last_in_bubbles = [];
                    _self.scope.bubbleArr = _self.last_in_bubbles;
                    _self.hanlder_group = _self.is_expand ? 0 : 2;
                    _self.environment('div.group-bubble-chat').trigger('click');
                }
            }
        });
        /*in out intem search*/
        _self.environment(_self.selector.main_container).find('.head-chat-search').unbind('click');
        _self.environment(_self.selector.main_container).find('.head-chat-search').on('click', function($event, $ui) {
            var __self = _self.environment(this);
            __self.find('.btn-serch').hasClass('none') ? __self.find('.btn-serch').removeClass('none') : __self.find('.btn-serch').addClass('none');
            __self.find('.btn-back').hasClass('none') ? __self.find('.btn-back').removeClass('none') : __self.find('.btn-back').addClass('none');
            !__self.find('.btn-back').hasClass('none') ? __self.find('input').removeAttr('readonly') : __self.find('input').attr('readonly', 'true');
        });
        /*setting toggle*/
        _self.environment(_self.selector.main_container).find('.head-chat-setting > p').unbind('click');
        _self.environment(_self.selector.main_container).find('.head-chat-setting > p').click(function() {
            _self.environment(_self.selector.main_container).find('.head-chat-setting-mode').toggle();
        });
    },
    bindOnHold: function(){
        var _self = this;
        callbackOnHold = function(){
            if(!angular.element('.bg-header-1').find('.nowrap')){
                setTimeout(function(){
                    callbackOnHold();
                }, 0);
            }
            else {
                setTimeout(function(){
                    _self.scope.$apply(function() {
                        angular.element('.bg-header-1').find('.nowrap').attr('on-hold', 'obj_chat_head.onHold()');
                        var _compile = angular.element('.bg-header-1').find('.nowrap');
                        _self.compile(_compile)(_self.scope).html();
                    })
                }, 2400);
            }
        }
        callbackOnHold();
    },
    refreshLayout: function($selector_ready) {
        var _self = this;
        _self.bindOnHold();
        _self.initShake();
        _self.environment($selector_ready).removeClass('none');
        _self.initDraggable(_self.environment(_self.selector.chat_container).find('.group-bubble'));
        _self.overLapChat();
        
    },
    setImgPicToUser: function($user_id) {
        var _self = this;
        var _item = _.findWhere(_self.user_message, {
            id: $user_id
        });
        return _item.image_pic;
    },
    setImgPicToGroup: function($group_id) {
        var _self = this;
        var _item = _.findWhere(_self.group_message, {
            id: $group_id
        });
        return _item.icon;
    },
    pullMessage: function($fn, $root_msg, $obj_message, $hanlder, $callback) {
        var _self = this;
        if (_self.lock_module) {
            return;
        }
        _self.scope.active_group = true;
        parseOKeyIsNumber(_self.user_message = $fn.copy(_self.scope.users));
        parseOKeyIsNumber(_self.group_message = $fn.copy(_self.scope.rooms));
        parseOKeyIsNumber(_self.obj_after_parse = $fn.copy($obj_message));
        _.extend(_self.obj_after_parse, {
            id: !Boolean($hanlder) ? parseInt(_self.obj_after_parse.from_user) : parseInt($root_msg.id), // user_id for user room_id for group
        });
        !Boolean($hanlder) && _self.obj_after_parse.room_id && _self.obj_after_parse.room_id == 0 ? _self.obj_after_parse.user_id = _self.obj_after_parse.from_user : '';
        _self.obj_after_parse.image_pic = _self.obj_after_parse.room_id && _self.obj_after_parse.room_id != 0 ? _self.setImgPicToGroup(_self.obj_after_parse.room_id) //
        : _self.setImgPicToUser(_self.obj_after_parse.id);
        if (_self.obj_after_parse.image_pic == '' || !Boolean(_self.obj_after_parse.image_pic)) {
            _self.obj_after_parse.image_pic = _self.obj_after_parse.room_id != 0 ? 'resources/images/thumnails/group-default.png' //
            : 'resources/images/thumnails/profile-default.png'
        }
        var _index = _.findLastIndex(_self.last_in_bubbles, {
            room_id: _self.obj_after_parse.room_id,
            id: _self.obj_after_parse.id,
        });
        if(parseInt(_self.obj_after_parse.room_id) > 0){
            _index = _.findLastIndex(_self.last_in_bubbles, {
                room_id: _self.obj_after_parse.room_id
            });
        }
        var _reverse = _self.environment('.in-window');
        if (_self.is_expand && _index != -1) {
            _self.last_in_bubbles[_index].counter = _self.obj_after_parse.counter;
            _reverse.each(function($index) {
                Boolean(_self.environment(this).hasClass('haschoose')) ? _self.last_in_bubbles[$index].counter = 0 : '';
            });
        } else {
            if (_index != -1) {
                _self.last_in_bubbles.splice(_index, 1);
            }
            var _hashtag = _.where(_self.last_in_bubbles, {
                hashtag: true
            });
            _.extend(_self.obj_after_parse, {
                on_active: _self.obj_after_parse.hashtag || _hashtag.length == 0 ? true : false
            });
            _.each(_self.last_in_bubbles, function($item, $index) {
                _.extend($item, {
                    on_active: _self.is_expand
                });
            });
            !_self.obj_after_parse.on_active ? _self.last_in_bubbles[0].on_active = true : '';
            // last bubble is has choose
            var _lock_last_choose = false;
            _reverse.each(function($index) {
                Boolean(_self.environment(this).hasClass('haschoose')) && $index == _self.limit_in_bubble - 1 ? _lock_last_choose = true : false;
            });
            _self.obj_after_parse.hashtag || _hashtag.length == 0 ? _self.last_in_bubbles.unshift($fn.copy(_self.obj_after_parse)) : _self.last_in_bubbles.splice(_hashtag.length, 0, $fn.copy(_self.obj_after_parse));
            _self.last_in_bubbles.length > _self.limit_in_bubble ? //
            (!Boolean(_lock_last_choose) ? _self.last_in_bubbles.pop() : _self.last_in_bubbles.splice(_self.limit_in_bubble - 2, 1)) : '';
        }
        return $callback(_self.last_in_bubbles, [_self.is_expand, _self.obj_after_parse]);
    },
};
chat_head = new chatHead($);