(function(){
    'use strict';

    angular.module('mons', [ 'ngResource', 'ngRoute', 'autocomplete' ])
        .config(function($routeProvider) {
            $routeProvider.
                when('/', {
                    controller: 'homeCtrl'
               }).
               otherwise({
                   redirectTo: '/'
               });
        })
        .config(function($logProvider){
            $logProvider.debugEnabled(true);
        })
        .service('dataApi', function($resource, context) {
            //console.log('dataApi',$resource, context);
            this.dataResource = $resource(context.urls.dataUrl);
        })
        .service('dataModel', function(dataApi, context) {
            //console.log('dataModel',this,dataApi);
            if(typeof context.categories_json !== 'undefined' && context.categories_json) {
                this.data = JSON.parse(context.categories_json);
            }
            else {
                this.data = dataApi.dataResource.get();
            }
        })
        .controller('homeCtrl', function($scope, $location, dataModel, context, $interval){

            function getURLParameter(name) {
                return decodeURI(
                    (new RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1]
                );
            }

            function colorToHex(c) {
                var m = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/.exec(c);
                return m ? '#' + (1 << 24 | m[1] << 16 | m[2] << 8 | m[3]).toString(16).substr(1) : c;
            }

            $scope.data = dataModel.data;

            var process_categories = function(data) {
                if(typeof data.categories!=='undefined' && data.categories.length>0){
                    var cats = [];
                    var nbCat = data.categories.length;
                    for(var i=0;i<nbCat;i++){
                        cats.push(data.categories[i].label);
                        if(typeof data.categories[i].subcategories!=='undefined' && data.categories[i].subcategories.length>0){
                            var nbSubCat = data.categories[i].subcategories.length;
                            for(var j=0;j<nbSubCat;j++){
                                cats.push(data.categories[i].subcategories[j].label);
                            }
                        }
                    }
                    if(typeof data.autocomplete === 'undefined' || data.autocomplete.length === 0) {
                        $scope.allCatLabels = cats;
                    }
                    else {
                        $scope.allCatLabels = data.autocomplete;
                    }
                }
            };

            if (typeof dataModel.data.$promise !== 'undefined') {
                dataModel.data.$promise.then(process_categories);
            }
            else {
                process_categories(dataModel.data);
            }

            $scope.selectedlevel = false;

            $scope.currentInterval = false;
            $scope.showSuccessAlert = false;
            $scope.showAlertDiv = false;
            function showAlert(m, success){
                $scope.alertMessage = m;
                $scope.showSuccessAlert = success;
                $scope.showAlertDiv = true;
                if(!$scope.$$phase) {
                    $scope.$apply();
                }
                if($scope.currentInterval){
                    $interval.cancel($scope.currentInterval);
                    $scope.currentInterval = false;
                }
                $scope.currentInterval = $interval(function(){ $interval.cancel($scope.currentInterval); $scope.showAlertDiv = false; }, 2000, 1);
            }
            $scope.annotPile = [];



            // Socket management
            var sock = null;
            var ellog = null;

            ellog = document.getElementById('log');
            function log(m) {
                if(ellog){
                    ellog.innerHTML += m + '\n';
                    ellog.scrollTop = ellog.scrollHeight;
                }
            }

            var wsuri;
            if (window.location.protocol === 'file:') {
                wsuri = 'ws://127.0.0.1:8090/annot';
            } else {
                wsuri = 'ws://' + window.location.hostname + ':8090/annot';
            }

            var eventCode = context.event_code;
            if(typeof eventCode==='undefined' || eventCode===''){
                eventCode = $location.search().event;
                if(typeof eventCode==='undefined' || eventCode===''){
                    eventCode = getURLParameter('event');
                    if(typeof eventCode==='undefined' || eventCode===''){
                        alert('le code de l\'événement doit être indiqué dans un paramètre de template u dans l\'url selon ?event=CODE_EVENEMENT.');
                        return;
                    }
                }
            }
            wsuri = wsuri + '?event=' + eventCode;

            if ('WebSocket' in window) {
                sock = new WebSocket(wsuri);
            } else if ('MozWebSocket' in window) {
                sock = new window.MozWebSocket(wsuri);
            } else {
                if(context.logging===true){
                    log('Browser does not support WebSocket!');
                }
                window.location = 'http://autobahn.ws/unsupportedbrowser';
            }

            if (sock) {
                sock.onopen = function() {
                    if(context.logging===true){
                        log('Connected to ' + wsuri);
                    }
                };

                sock.onclose = function(e) {
                    if(context.logging===true){
                        log('Connection closed (wasClean = ' + e.wasClean + ', code = ' + e.code + ', reason = ' + e.reason + ')');
                    }
                    showAlert('Communication interrompue : la socket vient de se fermer.', false);
                    sock = null;
                };

                sock.onmessage = function(e) {
                    var data_json = JSON.parse(e.data);
                    //console.log('1', data_json);
                    if(context.logging){
                        log('Got message: ' + e.data);
                    }
                    //showAlert('Annotation bien reçue.', true);
                    //console.log('2 message', $scope.annotPile.length);
                    if($scope.annotPile.length>0){
                        var c = $scope.annotPile.shift();
                        //console.log('3 message', c);
                        //console.log('2',data_json.status,data_json.status==='OK');
                        var ok = data_json.status==='OK';
                        var i;
                        if(c===false){
                            //showAlert('Annotation envoyée.', true);
                            $scope.sendBtnSuccess = ok;
                            $scope.sendBtnError = !ok;
                            i = $interval(function(){ $interval.cancel(i); $scope.sendBtnSuccess = false; $scope.sendBtnError = false; }, 2000, 1);
                        }
                        else{
                            c.sendSuccess = ok;
                            c.sendError = !ok;
                            i = $interval(function(){ $interval.cancel(i); c.sendSuccess = false; c.sendError = false; }, 2000, 1);
                        }
                        if(!$scope.$$phase) {
                            $scope.$apply();
                        }
                    }
                };
            }

            $scope.sendFreeAnnotation = function(label, text) {
                $scope.sendAnnotation(label, window.S(label).slugify().s, label, text, $scope.data.defaultColor || "#536991");
            };

            $scope.sendAnnotation = function(label, code, freeLabel, freetext, color, c){

                if($scope.username==='' || typeof $scope.username==='undefined'){
                    showAlert('Vous devez indiquer un nom d\'utilisateur.', false);
                    return;
                }
                if(label==='' || typeof label==='undefined'){
                    showAlert('Vous devez indiquer un nom de catégorie.', false);
                    return;
                }
                // Send query
                if (sock) {
                    if(typeof code==='undefined' || code===''){
                        code = window.S(label).slugify().s;
                    }

                    var hexc;
                    if(color.substring(0, 4) === 'rgb(') {
                        hexc = colorToHex(color);
                    }
                    else {
                        hexc = color;
                    }


                    var new_annot = {
                            category: {code: code, label: label},
                            text: freetext,
                            color: hexc,
                            user : $scope.username
                    };
                    sock.send(JSON.stringify(new_annot));
                 if(context.logging===true){
                        log('Sent: ' + JSON.stringify(new_annot));
                    }
                    if(typeof c==='undefined'){
                        $scope.annotPile.push(false);
                    }
                    else{
                        $scope.annotPile.push(c);
                    }
                    $scope.catText = "";
                    $scope.catLabel = "";
                } else {
                    showAlert('La socket ne fonctionne pas.', false);
                    if(context.logging===true){
                        log('Not connected.');
                    }
                }
            };

            // Interface management
            $scope.selectLevel = function(label, code, freelabel, freetext, color, c){
                if(typeof c==='undefined'){
                    $scope.returnVisStyle = {visibility:'hidden'};
                    $scope.selectedlevel = false;
                    return;
                }
                if(typeof c.subcategories!=='undefined' && c.subcategories.length>0){
                    $scope.selectedlevel = c.subcategories;
                    $scope.returnVisStyle = {visibility:'show'};
                }
                else{
                    // Send query
                    //console.log('send ntm', c);
                    $scope.sendAnnotation(label, code, freelabel, freetext, color, c);
                }
            };

        });

})();
