define([
        'knockout',
        'bluebird',
        'jquery',
        'videojs-contrib-hls',
        'tnc/tnc-tools',
        'service/widgetDataService',
        'tools/all',
        'tnc/tnc-transition',
        'widgets/transformation/ViewModel',
        'widgets/transformation/DomCollection',
        'widgets/transformation/TransformationPage'

    ],
    function() {
        'use strict';

        // Libs
        //var $ = require('jquery');
        var ko = require("knockout");
        //var videojs = window.videojs;

        //// Classes
        var DomCollection = require('widgets/transformation/DomCollection');
        var Promise = require('bluebird');
        //
        var TncTransition = require('tnc/tnc-transition');
        var TransformationPage = require('widgets/transformation/TransformationPage');

        //// Shortcuts to tools
        var tncTools = require('tnc/tnc-tools');
        var allTools = require('tools/all');
        var tools = allTools.tools;
        var validate = allTools.validate;
        var getNum = validate.getNum;
        var log = tools.log;

        // Services
        var widgetDataService = require('service/widgetDataService');

        var service = function() {
            var self = this;

            self.loadData = function(parentSettings, widgetSettings) {

                return widgetDataService.getWidgetData(parentSettings, widgetSettings)
                    .then(function(result) {
                        var items = result.items;
                        if (!Array.isArray(items)) {
                            items = [items];
                        }

                        return {
                            items: items,
                            templateData: result.data,
                            widgetSettings: widgetSettings,
                            parentSettings: parentSettings
                        };
                    });
            };

            self.loadTransformation = function(transformationData, $element) {
                return self.createPages(transformationData, $element);
            };

            self.createPages = function(transformationData, $element) {
                var items = transformationData.items;
                var domCollection = new DomCollection($element);
                var pageSize = transformationData.widgetSettings.amountOnPage || Math.max(1, items.length);
                var pageCount = Math.ceil(items.length / pageSize);

                var p = [];
                for (var i = 0; i < pageCount; i += 1) {
                    var pageItems = [];
                    for (var j = 0; j < pageSize; j += 1) {
                        var index = (i * pageSize) + j;
                        var item = items[index];
                        if (item) {
                            //item.isFinished = new DeferredPromise();
                            pageItems.push(item);
                        }
                        log('page:', i, 'item:', index);
                    }

                    var pageInfo = {
                        pageIndex: i,
                        pageCount: pageCount,
                        pageSize: pageSize,
                        pageItems: pageItems,
                        domCollection: domCollection
                    };

                    var resolveRelativeUrl = function(data) {
                        return tncTools.resourceUrl(transformationData.parentSettings.templateFolder, data);
                    };

                    p.push(self.createPage(pageInfo, transformationData, resolveRelativeUrl));
                }

                return Promise.all(p).then(function(pages) {
                    return pages;
                });
            };

            self.createPage = function(pageInfo, transformationData, resolveRelativeUrl) {
                var page = new TransformationPage(pageInfo, transformationData, resolveRelativeUrl);
                return page.load(); // returns Promise
            };

            self.play = function(pages, parentSettings) {
                var $prevPage = null;
                var prevPage = null;

                return Promise.each(pages, function(page, pageIndex, pageCount) {
                    log('playing page:', pageIndex, pages[pageIndex]);
                    var transition = new TncTransition(parentSettings.transition);
                    var duration = getNum(parentSettings.duration, 0) + transition.duration;
                    log('page duration', duration);
                    transition.transitionDisabled = (pageIndex === 0);
                    return page.preload().then(function() {
                            return transition.run(page.$element, $prevPage);
                        })
                        .then(function() {
                            if (prevPage) {
                                prevPage.$element.remove();
                                prevPage.$element = null;
                                ko.unapplyBindings(prevPage.$ko, true);
                                prevPage.$ko = null;
                                prevPage = null;
                                log('page unloaded', pageIndex - 1);
                            }
                        })
                        .then(page.play)
                        .then(function() {
                            prevPage = page;
                            $prevPage = page.$element;
                        })
                        .catch(function(err) {
                            // on error in the transformation knockout ignore
                            return Promise.resolve();
                        });
                });
            };

            self.pageReadyToPlay = function() {
                // transition + waiting here
                pageIndex += 1;
                setTimeout(function() {
                    playPage();
                }, duration);
            }
        }


        return new service();
    });
