/*
 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*jslint devel: true*/
/*global tizen, document, $, jQuery, app, TemplateManager,history, window,
  Helpers, setTimeout */

/**
* @class Ui
*/
function Ui() {
    'use strict';
    this.init();
}

(function strict() { // strict mode wrapper
    'use strict';

    Ui.prototype = {

        /**
         * UI remove mode
         * @type {boolean}
         */
        removeMode: false,

        /**
         * Default tizen address book
         * @type {AddressBook}
         */
        addressBook: tizen.contact.getUnifiedAddressBook(),

        /**
         * Default photo uri
         * @type {String}
         */
        photoURIdefault: null,

        /**
         * Cached contacts from address book
         * @type {Array}
         */
        contactsLoaded: null,

        /**
         * identifiers of currently checked checkboxes
         * @type {Array}
         */
        checkedLogs: [],

        /**
         * @type {TemplateManager}
         */
        templateManager: null,

        /**
         * UI Initializer
         */
        init: function Ui_init() {
            this.loadContacts();
            this.templateManager = new TemplateManager();
            this.helpers = new Helpers();
            $(document).ready(this.domInit.bind(this));
            $.mobile.tizen.disableSelection(document);
        },

        /**
         * When DOM is ready, initialise it (bind events)
         */
        domInit: function Ui_domInit() {
            this.templateManager.loadToCache(['callView',
                'callerHistory',
                'callItemRow',
                'callerCallItemRow',
                'messageWindow',
                'errorWindow',
                'dateRow'], this.initPages.bind(this));
        },

        /**
         * UI pages initializer
         */
        initPages: function Ui_initPages() {
            var pages = [], body = $('body');

            body
                .append(this.templateManager.get('messageWindow'))
                .append(this.templateManager.get('errorWindow'))
                .trigger('create');
            $('#callView')
                .append(
                    $(this.templateManager.get('callView')).children()
                )
                .trigger('pagecreate')
                .trigger('pageshow');
            pages.push(this.templateManager.get('callerHistory'));
            body.append(pages.join(''));
            this.removeSearchBarToHeader();

            this.addEvents();
            app.showCallHistory();

            this.photoURIdefault = $('#header .photo').css('background-image');
        },

        /**
        * Add UI events
        */
        addEvents: function Ui_addEvents() {
            var self = this;

            // recalculating page size when window resize
            // (eg. when soft keybord appear)
            $(window).on('resize', function onWindowResize() {
                $.mobile.activePage.page('refresh');
            });

            // creating call history view
            $('#callView').on('pagebeforeshow', function showCallHistory() {
                app.showCallHistory();
            });

            // creating single contact history view
            $('#historyForCallerView').on(
                'pagebeforeshow',
                function onCallerViewPageShow() {
                    self.hideCheckboxes();
                    // move scrollbar to top
                    $('#historyForCallerView')
                        .find('.ui-content.ui-scrollview-clip')
                        .find('.ui-scrollview-view')
                        .css('-webkit-transform', 'translate3d(0px, 0px, 0px)');
                    $('#selectAllDetails').on('change',
                        function onSelectAllChange() {
                            self.selectAll();
                        });
                }
            );

            $('#historyForCallerView').on(
                'pageshow',
                function onCallerViewPageShow() {
                    $('#content').css('top', '160px');
                    $('#header').css('height', '160px');
                    $('#callerListContainer')
                        .children(
                            '.ui-overflow-indicator-top',
                            '.ui-overflow-indicator-bottom'
                        ).hide();
                }
            );

            $('#callerListContainer').on(
                'scrollstart',
                function onCallerListScrollStart() {
                    $(this)
                        .children(
                            '.ui-overflow-indicator-top',
                            '.ui-overflow-indicator-bottom'
                        ).fadeIn(200);
                }
            );

            $('#callerListContainer').on(
                'scrollstop',
                function onCallerListScrollStop() {
                    $(this)
                        .children(
                            '.ui-overflow-indicator-top',
                            '.ui-overflow-indicator-bottom'
                        ).fadeOut(200);
                }
            );

            // selecting all checkboxes
            $('.selectAllBox').children().on(
                'click',
                function selectAllCheckboxes() {
                    $('.selectAllBox input[type=checkbox]').trigger('click');
                    self.selectAll();
                    self.selectAllDetailsEach();
                }
            );

            $('#calllogList').on(
                'click',
                '.date',
                function onCallLogDateClick(event) {
                    event.stopPropagation();
                }
            );

            // when clicked on a log display all history from that contact
            $('#calllogList').on(
                'click keypress',
                '.call',
                function onCalllogEntryClick(event) {
                    if (event.type === 'keypress' && event.keyCode !== 13) {
                        return;
                    }
                    var remoteParty = $(this)
                        .data('entries')[0]
                        .remoteParties[0]
                        .remoteParty;
                    app.showHistoryForCaller(remoteParty);
                    $.mobile.changePage('#historyForCallerView');
                }
            );

            // run sms service on click
            $('#smsActionBtn').on('click', function onSmsBtnClick(event) {
                event.stopPropagation();
                event.preventDefault();
                self.lockButtons('#smsActionBtn, #callActionBtn');
                self.hideCheckboxes();
                self.lockButtons('#deleteActionBtn');
                app.sendSms($('#forCallerList').data('remoteParty'));
            });

            // run call service on btn click
            $('#callActionBtn').on('click', function onCallBtnClick() {
                self.lockButtons('#callActionBtn, #smsActionBtn');
                self.hideCheckboxes();
                self.lockButtons('#deleteActionBtn');
                app.makeCall($('#forCallerList').data('remoteParty'));
            });

            $('#deleteActionBtn').on('click', function onDeleteBtnClick() {
                self.changeDetailsToRemoveState();
            });

            // selecting all checkboxes
            $('.selectAllBox').on('click', 'li', function onSelectAllClick() {
                var checkbox = $(this).find(':checkbox');
                if (self.removeMode === true) {
                    if (checkbox.prop('checked')) {
                        checkbox.prop('checked', false)
                            .data('checkboxradio')
                            .refresh();
                    } else {
                        checkbox.prop('checked', true)
                            .data('checkboxradio')
                            .refresh();
                    }
                    self.setSelectAllDetails();
                }
            });

            $('#popup')
                .on(
                    'click',
                    '#popupCancelActionBtn',
                    this.closePopup.bind(this)
                ).on(
                    'click',
                    '#popupSubmitActionBtn',
                    this.deleteCheckedLogs.bind(this)
                );

            $('#errorPopup').on(
                'click',
                '#errorPopupOkBtn',
                this.closeErrorPopup
            );

            $('#errorPopup').bind(
                {
                    popupafterclose: function onErrorPopupAfterClose() {
                        self.unlockButtons();
                    }
                }
            );

            $(window).keyup(function onWindowKeyUp(e) {
                if (e.which === 13) {
                    $('input:focus').blur();
                }
            });

            // bind hardware back button
            window.addEventListener('tizenhwkey', function onTizenHwKey(e) {
                if (e.keyName === 'back') {
                    // if there is any popup close it
                    if ($.mobile.popup.active) {
                        $.mobile.popup.active.close();
                    // if app is in remove mode close it
                    } else if (self.removeMode === true) {
                        app.ui.changeDetailsToRemoveState(undefined, true);
                    // if app is on calls page close app
                    } else if ($.mobile.activePage.attr('id') === 'callView') {
                        tizen.application.getCurrentApplication().exit();
                    // else back to calls page
                    } else {
                        history.back();
                    }
                }
            });
            // bind callback to visbility change event
            self.onVisibilityChange();
        },

        /**
         * Bind change event
         */
        addEventsForCallerListCheckboxes:
            function Ui_addEventsForCallerListCheckboxes() {
                var self = this;
                $('#forCallerList :checkbox').on('change',
                        function onCheckboxChange() {
                        self.setSelectAllDetails();
                    });
            },

        /**
         * Callback function for click on select all element
         */
        selectAll: function Ui_selectAll() {
            // select each checkbox separately
            this.selectAllDetailsEach();
        },

        /**
         * Select single checkbox and enable delete button
         * @param {jQuery} obj jQuery checkbox object
         * @param {boolean} state Checkbox state
         */
        selectCheckbox: function Ui_selectCheckbox(obj, state) {
            var deleteButton = $('#deleteActionBtn'), numChecked;
            // check checkbox and refresh its view
            obj.prop('checked', state)
                .data('checkboxradio')
                .refresh();

            // check if there is any checked checkbox
            // and toggle delete button availability
            numChecked = $('#forCallerList input:checked').length;
            if (this.removeMode && numChecked === 0) {
                deleteButton
                    .addClass('ui-disabled')
                    .attr('tabIndex', '-1')
                    .blur();
            } else if (deleteButton.hasClass('ui-disabled')) {
                deleteButton
                    .removeClass('ui-disabled')
                    .attr('tabIndex', '0');
            }
        },

        /**
         * Returns number of selected call logs
         * @return {number} length
         */
        getCountSelectedLogEntries: function Ui_getCountSelectedLogEntries() {
            return $('#forCallerList li .toRemove label.ui-checkbox-on').length;
        },

        /**
         * Select each checkbox separatly
         */
        selectAllDetailsEach: function Ui_selectAllDetailsEach() {
            var self = this;
            $('#forCallerList').find('input').each(function onInputIterate() {
                if ($('#selectAllDetails').prop('checked')) {
                    self.selectCheckbox($(this), true);
                } else {
                    self.selectCheckbox($(this), false);
                }
            });
        },

        /**
         * Hides checkboxes
         */
        hideCheckboxes: function Ui_hideCheckboxes() {
            var self = this;
            this.selectCheckbox($('#selectAllDetails'), false);

            $('#forCallerList').find('input').each(function onInputIterate() {
                self.selectCheckbox($(this), false);
            });
            this.changeDetailsToRemoveState('hide');
        },

        /**
         * Returns css classes for specified entry
         *
         * @param {CallHistoryEntry} entry
         * @returns {string}
         */
        cssClassesForEntry: function Ui_cssClassesForEntry(entry) {
            return 'call dir_' +
                entry.direction.toLowerCase() +
                ' type_' +
                entry.type.replace('.', '-').toLowerCase();
        },

        /**
         * Check if all details checkboxes are selected
         * and if so check selectAll element
         */
        setSelectAllDetails: function Ui_setSelectAllDetails() {
            if (
                $('#forCallerList input[type="checkbox"]').length ===
                    $('#forCallerList input[type=checkbox]:checked').length
            ) {
                this.selectCheckbox($('#selectAllDetails'), true);
            } else {
                this.selectCheckbox($('#selectAllDetails'), false);
            }
        },

        /**
         * Shows popup with specified message
         * @param {string} message
         */
        showPopup: function Ui_showPopup(message) {
            $('#popupMessage').html(message);
            $('#popup').popup('open', {'positionTo': 'window'});
        },

        /**
         * Hides popup
         */
        closePopup: function Ui_closePopup() {
            $('#popup').popup('close');
        },

        /**
         * Display error popup
         */
        showErrorPopup: function Ui_showErrorPopup(message) {
            $('#errorPopupMessage').html(message);
            $('#errorPopup').popup('open', {'positionTo': 'window'});
        },

        /**
         * Hides error popup
         */
        closeErrorPopup: function Ui_closeErrorPopup() {
            $('#errorPopup').popup('close');
        },

        /**
         * Deletes checked log entries
         */
        deleteCheckedLogs: function Ui_deleteCheckedLogs(e) {
            // if there is popup open close it
            this.closePopup();

            // uncheck SelectAll checkbox
            this.selectCheckbox($('#selectAllDetails'), false);

            // iterate through all entries
            $('#forCallerList li.call').each(function onCallEntryIterate() {
                // if entry contains selected checkbox
                if ($(this).find('form label').hasClass('ui-checkbox-on')) {
                    // remove that entry
                    app.deleteLog($(this).data('entries')[0]);
                    // and remove connected html element
                    $(this).remove();
                }
            });

            // if there are still some entries
            if ($('#forCallerList li.call').length > 0) {
                // update header info
                this.updateCallerHeaderNumberOfEntries(
                    $('#forCallerList li.call').length
                );
            } else {
                // if no entries change page
                e.preventDefault();
                $('.ui-listview-filter .ui-input-text').val('');
                $('.ui-listview-filter .ui-input-text').trigger('change');
                $.mobile.changePage('#callView');
            }

            this.changeDetailsToRemoveState(true);
        },

        changeDetailsToRemoveState: function Ui_changeDetailsToRemoveState(
            set,
            clear
        ) {
            var counter = this.getCountSelectedLogEntries(),
                numChecked = $('#forCallerList input:checked').length,
                matrix,
                pos;
            if (clear === true) {
                counter = 0;
                // uncheck all checkboxes
                $('#forCallerList').find(':checkbox').prop('checked', false)
                    .data('checkboxradio').refresh();
                $('.selectAllBox').find(':checkbox').prop('checked', false)
                    .data('checkboxradio').refresh();
            }

            if (set) {
                this.removeMode = false;
            } else if (counter === 0) {
                this.removeMode = !this.removeMode;
            }

            // if app is in remove mode and there are no selected checkboxes
            if (this.removeMode && numChecked === 0) {
                // disable delete button
                $('#deleteActionBtn')
                    .addClass('ui-disabled')
                    .attr('tabIndex', '-1')
                    .blur();
            // if app is not in removeMode
            } else if (!this.removeMode) {
                // set delete button to enabled
                $('#deleteActionBtn')
                    .removeClass('ui-disabled')
                    .attr('tabIndex', '0');
                this.selectAllDetailsEach();
            }

            // if there are no selected entries
            if (counter === 0) {
                // again checking removeMode
                if (this.removeMode) {
                    // show buttons from remove mode
                    $('#historyForCallerView .toRemove').removeClass('hidden');
                    $('#historyForCallerView .selectAllBox')
                        .removeClass('hidden');
                } else {
                    $('#historyForCallerView .toRemove').addClass('hidden');
                    $('#historyForCallerView .selectAllBox').addClass('hidden');
                }
            } else {
                this.showPopup(
                    counter > 1 ?
                            'Are you sure you want to delete selected logs?' :
                            'Are you sure you want to delete selected log?'
                );
            }

            // fix scrollview
            matrix =
                $('#historyForCallerView .ui-scrollview-view')
                .css('transform');
            pos = matrix.substr(7, matrix.length - 8).split(',')[5];
            if (pos !== undefined) {
                $('#callerListContainer')
                    .scrollview('scrollTo', 100, parseInt(pos, 10), 10);
            } else {
                this.refreshScrollView();
            }
        },

        /**
         * Renders call history list
         *
         * @param {CallHistoryEntry[]} callEntries
         */
        showCallHistory: function Ui_showCallHistory(callEntries) {
            var self = this,
                pdate = null, // previous date
                date = '',
                elements = [], // list elements
                len = callEntries.length, // entries length
                tempLength = 0, // length of temporary table;
                i, // loop counter
                j, // loop counter
                current, // current entry object
                filterResult,
                groupsOfDays = [],
                dayLog,
                index = 0,
                calllogList = $('#calllogList'),
                calllogListContent = $('#calllogListContent'),
                searchInput = $('#callView .input-search-bar input'),
                calllogListContentPos;

            // return duplicated entries
            function filterForSameEntry(element) {
                return self.getNumber(current) === self.getNumber(element) &&
                    current.direction === element.direction;
            }

            $('.selectedCount').hide();

            for (i = 0; i < len; i = i + 1) {
                current = callEntries[i];
                date = this.helpers.toNativeDate(current.startTime);

                // if date is changed create new deyLog;
                if (date !== pdate) {
                    dayLog = {};
                    dayLog.date = date;
                    dayLog.entries = [];
                    dayLog.counters = [];
                    groupsOfDays.push(dayLog);
                    pdate = date;
                }

                // group entries by remote Party;
                filterResult = dayLog.entries.filter(filterForSameEntry);
                if (filterResult.length) {
                    index = dayLog.entries.indexOf(filterResult[0]);
                    dayLog.counters[index] += 1;
                } else {
                    dayLog.entries.push(current);
                    dayLog.counters[dayLog.entries.length - 1] = 1;
                }
            }
            // Create UL list with dividers;
            len = groupsOfDays.length;
            for (i = 0; i < len; i += 1) {
                dayLog = groupsOfDays[i];
                tempLength = dayLog.entries.length;
                for (j = 0; j < tempLength; j = j + 1) {
                    elements.push(
                        this.getCallItemRow(
                            dayLog.entries[j],
                            dayLog.counters[j]
                        )
                    );
                }
            }
            calllogListContentPos = this.helpers.getScrollPosition(
                calllogListContent
            );
            calllogList.empty().append(elements);
            // searching phrase
            if (searchInput.val().length > 0) {
                calllogList.listview('refresh');
                searchInput.trigger('keyup');
                $('.ui-li-divider')
                    .removeClass('ui-li ui-li-divider ui-bar-s')
                    .addClass('date');
            } else {
                calllogList.listview({
                    autodividers: true,
                    autodividersSelector: function onDividersIterate(li) {
                        return $(li).find('.callDate').text() ===
                            app.ui.helpers.toNativeDate(new Date()) ?
                                    'Today' : $(li).find('.callDate').text();
                    }
                }).listview('refresh');
                $('.ui-li-divider').removeClass().addClass('date');
            }

            setTimeout(
                this.helpers.scrollTo.bind(
                    this,
                    calllogListContent,
                    calllogListContentPos
                ),
                10
            );
        },

        /**
         * @param {CallHistoryEntry} entry
         */
        getNumber: function Ui_getNumber(entry) {
            return entry.remoteParties[0].remoteParty;
        },

        /**
         * Returns HTML for single log entry
         *
         * @param {CallHistoryEntry} entry
         * @param {number} counter
         * @returns {HTMLPartial}
         */
        getCallItemRow: function Ui_getCallItemRow(entry, counter) {
            var party = entry.remoteParties[0],
                name = this.getNameByNumber(party.remoteParty),
                tpl;

            if (counter > 1) {
                name += ' (' + counter + ')';
            }

            // prepare html string
            tpl = this.templateManager.get('callItemRow', {
                'name': name,
                'callTime': this.helpers.toNativeTime(entry.startTime),
                'callDate': this.helpers.toNativeDate(entry.startTime),
                'cssClasses': this.cssClassesForEntry(entry),
                'uid': entry.uid
            });

            // return clean DOM element so that array of those could be appended
            // at once
            return $(tpl)
                .data('remoteParty', entry.remoteParties[0].remoteParty)
                .data('entries', [entry])
                .get(0);
        },

        /**
         * Return readable number identifier
         *
         * @param {string} number
         * @returns {string}
         */
        getNameByNumber: function Ui_getNameByNumber(number) {
            var i = 0,
                j = 0,
                contact = null,
                name = '',
                numbers = null;

            // iterate through loaded contacts
            for (i in this.contactsLoaded) {
                if (this.contactsLoaded.hasOwnProperty(i)) {
                    contact = this.contactsLoaded[i];
                    numbers = contact.phoneNumbers;
                    // iterate through numbers of contact
                    for (j in numbers) {
                        // check if first 9 characters match number
                        if (numbers.hasOwnProperty(j) &&
                            numbers[j].number.replace(/\s/g, '').substr(-9) ===
                                number.substr(-9)) {
                            // get display name
                            name = contact.name.displayName;
                            break;
                        }
                    }
                }
            }
            return name || number || 'Unknown';
        },

        /**
         * Returns HTML for single caller log entry
         *
         * @param {CallHistoryEntry} entry
         * @returns {HTMLElement}
         */
        getCallerCallLogRow: function Ui_getCallerCallLogRow(entry) {
            return $(this.templateManager.get('callerCallItemRow', {
                'cssClass': this.cssClassesForEntry(entry),
                'callTime': this.helpers.toNativeTime(entry.startTime),
                'callDuration': this.helpers.secondsToHours(entry.duration),
                'uid': entry.uid
            })).data('entries', [entry]).get(0);
        },

        /**
         * Renders call log list for specified caller
         *
         * @param {string} remoteParty
         * @param {CallHistoryEntry[]} entries
         */
        showHistoryForCaller: function Ui_showHistoryForCaller(
            remoteParty,
            entries
        ) {
            var pdate = '', // previous data
                date = '',
                elements = [],
                len = entries.length, // number of entries
                i,
                checkbox;

            if (len) {
                this.updateCallerHeader(entries[0], entries.length);
            } else {
                // if last call log has been removed
                this.removedLastLog();
                this.app.lastViewedCaller = 0;
            }

            // clean the list
            $('#forCallerList')
                .data('remoteParty', remoteParty)
                .data('modified', false)
                .empty();

            // group caller log entries by date
            for (i = 0; i < len; i = i + 1) {
                date = this.helpers.toNativeDate(entries[i].startTime);

                // if date is changed render new header
                if (date !== pdate) {
                    elements.push(
                        $(this.templateManager.get(
                            'dateRow',
                            {'date': date}
                        )).get(0)
                    );
                    pdate = date;
                }
                elements.push(this.getCallerCallLogRow(entries[i]));
            }

            $('#forCallerList')
                .empty()
                .append(elements);

            // set state of delete button
            if (elements.length > 0) {
                $('li#delete > a').addClass('ui-btn-active');
            } else {
                $('li#delete > a').removeClass('ui-btn-active');
            }

            $('#forCallerList').trigger('create');

            // change to remove mode if it was active before registering call
            if (this.removeMode) {
                this.removeMode = !this.removeMode;
                this.changeDetailsToRemoveState(false);
                // check previous checked entries
                this.checkedLogs.forEach(function onLogsIterate(logUid) {
                    checkbox =
                        $('#forCallerList li.call[data-uid="' + logUid + '"]')
                        .find(':checkbox');
                    if (checkbox.length > 0) {
                        checkbox.prop('checked', true)
                            .data('checkboxradio')
                            .refresh();
                        $('#deleteActionBtn')
                            .removeClass('ui-disabled')
                            .attr('tabIndex', '0');
                    }
                });

                this.setSelectAllDetails();

                // close popup if there are no checked checkboxes
                if (!$('#forCallerList input:checked').length) {
                    if ($.mobile.popup.active) {
                        $.mobile.popup.active.close();
                    }
                }
            }
            this.addEventsForCallerListCheckboxes();
            // lock buttons if unknown caller
            if (remoteParty) {
                this.unlockButtons();
            } else {
                this.lockButtons(
                    '#callActionBtn, #smsActionBtn, #deleteActionBtn'
                );
            }
        },

        /**
         * Update accoundId
         * @param {string} accountId
         */
        updateCallerHeaderAccountId: function Ui_updateCallerHeaderAccountId(
            accountId
        ) {
            $('.infoContainer .accountId').html(accountId);
        },

        /**
         * Update number of entries
         * @param numberOfEntries
         */
        updateCallerHeaderNumberOfEntries:
            function Ui_updateCallerHeaderNumberOfEntries(numberOfEntries) {
                $('.infoContainer .numberOfEntries').html(
                    numberOfEntries +
                        ' ' +
                        (numberOfEntries === 1 ? 'call' : 'calls')
                );
            },

        /**
         * Updates caller main info
         * @param {CallHistoryEntry} entry
         * @param {number} numberOfEntries
         */
        updateCallerHeader: function Ui_updateCallerHeader(
            entry,
            numberOfEntries
        ) {
            var name = '', party, imgPath, personId;

            $('#header .photo').css('background-image', this.photoURIdefault);

            if (entry.remoteParties !== null) {
                party = entry.remoteParties[0];
                personId = parseInt(party.personId, 10);
                name = this.getNameByNumber(party.remoteParty);
                if (party.displayName) {
                    this.updateCallerHeaderAccountId(party.remoteParty);
                }
                this.updateCallerHeaderNumberOfEntries(numberOfEntries);
                if (personId !== 0) {
                    imgPath = app.getPhotoURIForContact(personId);
                    if (imgPath !== false) {
                        $('#header .photo')
                            .css('background-image', 'url(' + imgPath + ')');
                    }
                }
            } else if (entry.contactId !== null) {
                name = entry.accountId;
                this.updateCallerHeaderAccountId(entry.accountId);
                this.updateCallerHeaderNumberOfEntries(numberOfEntries);
            } else {
                name = entry.accountId;
                this.updateCallerHeaderAccountId('');
                this.updateCallerHeaderNumberOfEntries(numberOfEntries);
            }
            $('.contact > .infoContainer > .name').html(
                this.templateManager.modifiers.escape(name)
            );
        },

        /**
         * Finds contacts
         * @param {function} callback
         */
        loadContacts: function Ui_loadContacts(callback) {
            var contactsFoundCB, errorCB;

            this.contactsLoaded = null;

            contactsFoundCB = function onContactsFindSuccess(contacts) {
                this.contactsLoaded = contacts;
                if (callback instanceof Function) {
                    callback();
                }
            };

            errorCB = function onContactFindError(error) {
                console.error(
                    'Model_loadContacts, problem with find() method: ' +
                        error.message
                );
            };

            this.addressBook.find(contactsFoundCB.bind(this), errorCB);
        },

        /**
         * Remove search filter from content and appends it to header
         */
        removeSearchBarToHeader: function Ui_removeSearchBarToHeader() {
            var activePage = $.mobile.activePage;

            // Move filter to header
            $('#page-header').append($('#callView .ui-listview-filter'));
            // Add missing class to header
            activePage.find('.ui-header').addClass('ui-header-searchbar');

            activePage.page('refresh');
        },

        /**
         * Binding visibility state change event
         */
        onVisibilityChange: function Ui_onVisibilityChange() {
            var self = this;
            document.addEventListener('webkitvisibilitychange',
                function onVisibilityChange() {
                    if (document.webkitVisibilityState === 'hidden') {
                        self.updateCheckboxes();
                    } else {
                        self.loadContacts(app.updateCallLists.bind(app));
                        $('#callActionBtn, #smsActionBtn')
                            .removeClass('ui-disabled');
                    }
                });
        },

        /**
         * Store uid of checked entries in checkedLogs Array
         */
        updateCheckboxes: function Ui_updateCheckboxes() {
            // empty checkedLogs logs array
            var checkedLogs = [];
            this.checkedLogs = checkedLogs;
            // iterate through the entries
            $('#forCallerList li.call').each(function onCallRecordIterate() {
                // if entry cotains checked checkbox
                if ($(this).find('form label').hasClass('ui-checkbox-on')) {
                    var checkedEntry = $(this).data('entries')[0];
                    // push the entry uid to checkedLogs array
                    checkedLogs.push(checkedEntry.uid);
                }
            });
        },

        /**
         * Disabling element
         * @param {jQuery} buttons
         */
        lockButtons: function Ui_lockButtons(buttons) {
            $(buttons).addClass('ui-disabled').attr('tabIndex', '-1').blur();
        },

        /**
         * Enabling element
         */
        unlockButtons: function Ui_unlockButtons() {
            $('#callActionBtn, #smsActionBtn, #deleteActionBtn')
                .removeClass('ui-disabled')
                .attr('tabIndex', '0');
        },

        /**
         * Patch for UI, bad refresh scrollView
         */
        refreshScrollView: function Ui_refreshScrollView() {
            var scrollView = $('.ui-scrollview-view'),
                show = function scrollViewShow() {
                    scrollView.show();
                };
            scrollView.hide();
            setTimeout(show, 0);
        },

        /**
         * Handle event when last log is removed
         */
        removedLastLog: function Ui_removedLastLog() {
            this.hideCheckboxes();
            $('.ui-popup').popup('close');
            $.mobile.changePage('#callView');
        }
    };

}());
