/*
 * Copyright (c) 2013 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.
 */

/*global $, app, TemplateManager, UiEvents, localStorage, console,
document */

/**
 * @class Ui
 */

function Ui() {
    'use strict';
    return;
}

(function strict() {
    'use strict';

    Ui.prototype = {
        /**
         * @type {TemplateManager}
         */
        templateManager: null,

        /**
         * @type {UiEvents}
         */
        uiEvents: null,

        /**
         * Download operation status
         * @type {object}
         */
        downloadStatuses: {
            completed: 'Completed',
            failed: 'Failed'
        },

        /**
         * Images which need to be preloaded on initialization.
         * @type {string[]}
         */
        imagesToPreload: [
            'images/cancel.png',
            'images/delete.png',
            'images/folder.png',
            'images/myfile_excel.png',
            'images/myfile_html.png',
            'images/myfile_images.png',
            'images/myfile_music.png',
            'images/myfile_pdf.png',
            'images/myfile_ppt.png',
            'images/myfile_svg.png',
            'images/myfile_swf.png',
            'images/myfile_text.png',
            'images/myfile_unsupport.png',
            'images/myfile_video.png',
            'images/myfile_word.png',
            'images/pause.png',
            'images/play.png',
            'images/refresh.png',
            'images/stop.png'
        ],

        /**
         * Initialization.
         * @param {function} [initializedCallback]
         */
        init: function Ui_init(initializedCallback) {
            initializedCallback = initializedCallback || function noop() {
                return;
            };

            this.templateManager = new TemplateManager();
            this.uiEvents = new UiEvents(this);
            $(document).ready(
                this.uiEvents.init.bind(
                    this.uiEvents,
                    this.imagesPreload.bind(
                        this,
                        this.imagesToPreload,
                        initializedCallback
                    )
                )
            );
            $.mobile.tizen.disableSelection(document);
        },

        /**
         * Preloads images
         * @param {string[]} images
         * @param {function} callback
         */
        imagesPreload: function imagesPreload(images, callback) {
            $(images).each(function onIterate() {
                $('<img/>')[0].src = this;
            });
            callback();
        },

        /**
         * Renders download operations list.
         */
        showList: function Ui_showList(downloads) {
            this.templateManager.loadToCache(['download-row'], function load() {
                var id = null,
                    listElement = null,
                    ul = $('#main-content ul.ui-listview'),
                    retrievedObject = {},
                    fileIcon = '',
                    i = 0,
                    length = downloads.length;

                for (i = 0; i < length; i += 1) {

                    retrievedObject = downloads[i];
                    id = retrievedObject.id;
                    fileIcon = app.helpers.resolveFileIcon(
                        app.helpers.getFileExtension(
                            retrievedObject.fileName
                        )
                    );

                    listElement = this.templateManager.get('download-row', {
                        downloadId: id,
                        fileName: retrievedObject.fileName,
                        url: retrievedObject.url,
                        fileIcon: fileIcon
                    });

                    ul.append(listElement).listview('refresh');
                    if (retrievedObject.state === 100) {
                        ul
                            .find('#progressbar' + id)
                            .progress({value: 0})
                            .css('visibility', 'hidden');
                        ul.find('#delete' + id).attr('data-icon', 'cancel');
                        ul.find('#button' + id).attr('data-icon', 'folder');
                        ul.find('#delete' + id).attr('state', 'finished');
                        ul.find('#button' + id).attr('state', 'finished');
                    } else {
                        ul
                            .find('#progressbar' + id)
                            .progress({value: retrievedObject.state});
                        ul.find('#delete' + id).attr('data-icon', 'cancel');
                        ul.find('#button' + id).attr('data-icon', 'play');
                        ul.find('#delete' + id).attr('state', 'pause');
                        ul
                            .find('#button' + id)
                            .attr('listener-flag', '0')
                            .attr('state', 'pause');
                    }
                    ul.find('#delete' + id).button();
                    ul.find('#button' + id).button();

                }
            }.bind(this));
        },

        /**
         * Adds new record to download list
         * @param {number} id Download ID
         * @param {string} url Resource URL
         * @param {string} fileName File name
         */
        addDownloadRecordToList: function Ui_addDownloadRecordToList(
            id,
            url,
            fileName
        ) {
            var ul = $('#main-content ul.ui-listview'),
                fileIcon = app.helpers.resolveFileIcon(
                    app.helpers.getFileExtension(fileName)
                ),
                listElement = this.templateManager.get('download-row', {
                    downloadId: id,
                    fileName: fileName,
                    url: url,
                    fileIcon: fileIcon
                });

            ul.prepend(listElement).listview('refresh');
            ul.find('#progressbar' + id).progress({value: 0});
            ul.find('#delete' + id).button();
            ul.find('#button' + id).button();
        },

        /**
         * Hides specified button
         * @param {object} button HTML Input button object
         * @param {number} state Download operation state
         */
        hideButton: function Ui_hideButton(button, state) {
            button.css('visibility', 'hidden');
            button.attr('state', state);
            button.button('refresh');
        },

        /**
         * Changes image on specified button
         * @param {object} obj
         * @param {number} state Download operation state
         * @param {string} icon Icon type
         */
        changeButtonImage: function Ui_changeButtonImage(obj, state, icon) {
            obj.attr('state', state).attr('data-icon', icon);
        },

        /**
         * Shows notification
         * @param {number} id Download ID
         * @param {string} message Notofication content
         */
        showNotification: function Ui_showNotification(id, message) {
            var notification = document.createElement('div'),
                downloadControl = $('#' + id + ' .download-control')[0];

            notification.className = 'sub';
            notification.textContent = message;
            downloadControl.appendChild(notification);
        },

        /**
         * Checks if download record exists
         * @param {number} id Download ID
         * @returns {boolean}
         */
        isDownloadRecord: function Ui_isDownloadRecord(id) {
            var result = false;
            if ($('#' + id).length > 0) {
                result = true;
            }
            return result;
        },

        /**
         * Performs UI changes when download operation started successfully.
         * @param {number} id Download ID
         * @param {string} url Resource URL
         * @param {string} fileName
         */
        onDownloadStarted: function Ui_onDownloadStarted(
            id,
            url,
            fileName
        ) {

            if (!this.isDownloadRecord(id)) {
                this.addDownloadRecordToList(
                    id,
                    url,
                    fileName
                );
            }
            $('#' + id).attr('id', id);
            $('#name' + id).attr('id', 'name' + id);
            $('#progressbar' + id).attr('id', 'progressbar' + id);
            $('#button' + id)
                .attr('id', 'button' + id)
                .attr('for-download', id);
            $('#delete' + id)
                .attr('id', 'delete' + id)
                .attr('for-download', id);
            this.onDownloadResumed(id);
        },

        /**
         * Performs UI changes when download operation resumed successfully.
         * @param {number} id Download ID.
         */
        onDownloadResumed: function Ui_onDownloadResumed(id) {
            var playButton = $('#button' + id);

            playButton.attr('listener-flag', '1');

            this.changeButtonImage(playButton, 'play', 'pause');
            this.changeButtonImage($('#delete' + id), 'play', 'stop');
        },

        /**
         * Performs UI changes when download operation is in progress state.
         * @param {number} id Download ID
         * @param {number} receivedSize
         * @param {number} totalSize
         */
        onDownloadProgress: function Ui_onDownloadProgress(
            id,
            receivedSize,
            totalSize
        ) {
            var obj = $('#button' + id), progressBar, state;

            if (obj.attr('state') !== 'play') {
                this.changeButtonImage(obj, 'play', 'pause');
            }

            progressBar = $('#progressbar' + id);
            if (progressBar.length) {
                state = Math.floor((receivedSize / totalSize) * 100);
                progressBar.progress('value', state);
            }
        },

        /**
         * Performs UI changes when download operation completed successfully.
         * @param {number} id Download ID
         * @param {string} fileName File name
         */
        onDownloadCompleted: function Ui_onDownloadCompleted(
            id,
            fileName
        ) {
            var progressBar = $('#progressbar' + id);

            $('#name' + id).html(fileName);
            this.changeButtonImage($('#button' + id), 'finished', 'folder');
            this.changeButtonImage($('#delete' + id), 'finished', 'cancel');

            if (progressBar.length > 0) {
                progressBar.css('visibility', 'hidden');
            }

            this.showNotification(
                id,
                this.downloadStatuses.completed
            );
        },

        /**
         * Performs UI changes when download operation was paused.
         * @param {number} id Download ID
         */
        onDownloadPaused: function Ui_onDownloadPaused(id) {
            this.changeButtonImage($('#button' + id), 'pause', 'play');

            this.changeButtonImage($('#delete' + id), 'pause', 'cancel');
        },

        /**
         * Performs UI changes when download operation was cancelled.
         * @param {number} id Download ID
         */
        onDownloadCanceled: function Ui_onDownloadCanceled(id) {
            this.changeButtonImage($('#button' + id), 'canceled', 'play');

            this.changeButtonImage($('#delete' + id), 'canceled', 'cancel');

            $('#main-content ul.ui-listview')
                .find('#progressbar' + id)
                .progress({value: 0})
                .progress('refresh');
        },

        /**
         * Performs UI changes when download operation failed.
         * Triggers displaying notification with reason of fail.
         *
         * @param {number} id Download ID
         * @param {string} message reason of download fail.
         */
        onDownloadFailed: function Ui_onDownloadFailed(id, message) {
            console.log('Ui_onDownloadFailed:', id, message);
            var progressBar = $('#progressbar' + id);

            progressBar.css('visibility', 'hidden');
            this.hideButton($('#button' + id), 'failed');

            this.changeButtonImage($('#delete' + id), 'failed', 'cancel');

            this.showNotification(id,
                this.downloadStatuses.failed + ' - ' + message);
        },

        /**
         * Removes download operation row and related localStorage record.
         * @param {number} id Download ID.
         */
        deleteDownloading: function Ui_deleteDownloading(id) {
            $('#' + id).remove();
        },

        /**
         * Refreshes download list.
         * @param {object[]} downloads Download history list.
         * @param {object} filesDataList
         */
        refreshDownloadsList: function Ui_refreshDownloadsList(
            downloads,
            filesDataList
        ) {
            console.log('Ui_refreshDownloadsList', filesDataList);

            var retrievedObject = null,
                filesDataObj = null,
                i = 0,
                length = downloads.length;
            for (i = 0; i < length; i += 1) {
                retrievedObject = downloads[i];
                filesDataObj = filesDataList[retrievedObject.fileName];

                if (
                        filesDataObj === undefined ||
                        (filesDataObj !== retrievedObject.receivedSize &&
                            retrievedObject.state === 100)
                ) {
                    app.deleteDownloading(retrievedObject.id);
                }
            }
        }
    };

}());
