(function () {

    'use strict';

    class ProgressService {
        static $inject = ['$uibModal', 'ufSession'];
        constructor(private $uibModal: angular.ui.bootstrap.IModalService, private ufSession) {
        }

        createProgress(title: string): angular.IPromise<Progress> {
            var progress: Progress = new Progress(this.$uibModal, title, this.ufSession);
            return this.$uibModal.open({
                templateUrl: 'ds/progress.html',
                controllerAs: 'vm',
                controller: ['$scope', progress.createModalControllerInstance],
                backdrop: 'static'
            }).opened
                .then(() => {
                    return progress;
                });
        }
    }

    interface EventData {
        isFirstUpdate?: boolean;
        name?: string;
        isComplete?: boolean;
        percent?: number;
        subActivity?: string;
        description?: string;
    }

    interface Cancel {
        (): angular.IPromise<void>;
    }


    class Progress {

        private modalController: ModalController;
        constructor(private $uibModal: angular.ui.bootstrap.IModalService, private title: string, private ufSession) {
        }

        private dialogNames: string[] = [];
        handleEvent(event: EventData, cancel: Cancel) {

            this.modalController.update(event, cancel);
            if (event.isFirstUpdate) {
                this.dialogNames.push(event.name);
                this.modalController.updateDescription(event.name);

            } else if (event.isComplete) {
                this.dialogNames.pop();
                this.modalController.updateDescription(this.dialogNames[this.dialogNames.length - 1]);
            }
        }

        close() {

            this.modalController.closeModal();
        }

        createModalControllerInstance = ($scope: angular.ui.bootstrap.IModalScope): ModalController => {
            this.modalController = new ModalController($scope, this.title, this.ufSession);
            return this.modalController;
        };

    }

    class ModalController {
        event: EventData = {};
        cancel: Cancel;
        description: string = '';

        constructor(private $scope: angular.ui.bootstrap.IModalScope, public title: string, public ufSession)  {
        }

        updateDescription(value: string) {
            this.description = value;
        }

        cancelClicked() {
            if (this.cancel) {
                this.cancel().finally(this.$scope.$dismiss);
            }
        }

        update(event: EventData, newCancelHandler: Cancel) {

            this.cancel = newCancelHandler;

            // update the even object
            this.event = event;
            // this is may be an external event, so we need this to have the changes take effect
            if (!this.$scope.$$phase) {
                this.$scope.$apply();
            }
        }

        closeModal() {
            this.$scope.$dismiss();
        }

        isPercentType() {
            return this.event.percent || this.event.percent === 0;
        }
        
        isSerial() {
            return this.ufSession.isSerial();
        }
    }

    angular.module('uniflash').service('ufProgess', ProgressService);

})();