var wsUri = "ws://" + window.location.hostname + ":" + window.location.port + "/live.json";
// var wsUri = "ws://localhost:8081/live.json";
function getConfig() {
    var seconds = localStorage.getItem('seconds');
    if (seconds == null) {
        return { status: 2592000, gps: 86400, age: 3600 };
    } else {
        seconds = JSON.parse(seconds || '');
        return { status: seconds.status, gps: seconds.gps, age: seconds.age };
    }
}
function ToJavaScriptDate(value) {
    var pattern = /Date\(([^)]+)\)/;
    var results = pattern.exec(value);
    if (parseFloat(results[1]) < 0) {
        return null;
    }
    var dt = new Date(parseFloat(results[1]));
    //dt.setMonth(dt.getMonth() + 1);
    return dt;
}
var app = angular.module('tetraApp', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {

    $routeProvider.when('/live', {
        templateUrl: 'views/live.html',
        controller: 'TetraCtrlLive'
    }).when('/sds/:radio?/:ssi?', {
        templateUrl: 'views/sds.html',
        controller: 'TetraCtrlSds'
    }).when('/map', {
        templateUrl: 'views/map.html',
        controller: 'TetraCtrlMap'
    }).when('/status', {
        templateUrl: 'views/status.html',
        controller: 'TetraCtrlStatus'
    }).when('/config', {
        templateUrl: 'views/config.html',
        controller: 'TetraCtrlCfg'
    }).when('/status_table/:viewName?', {
        templateUrl: 'views/status_table.html',
        controller: 'TetraCtrlStatusTable'
    }).otherwise({
        redirectTo: '/live'
    });
}
]);
app.filter('bytypes', function () {
    return function (datas, types) {
        var items = {
            types: types,
            out: []
        };
        if (types === undefined) {
            return;
        }
        angular.forEach(datas, function (value, key) {
            if (this.types[value.type] === true) {
                this.out.push(value);
            }
        }, items);
        return items.out;
    }

});
app.controller('TetraCtrlStatusTable', function ($scope, $routeParams, $filter, $route) {

    $scope.data = {
        ProtocolID: 130
    };
    $scope.radios = [];
    $scope.issis = [];

    function getDefault() {
        return {
            label: 'Standard Ansicht',
            height: 100,
            font: 16,
            width: 18,
            items: []
        };
    }
    $scope.loadItem = function (issi) {
        $.get('/api/issi.json?issi=' + issi.ISSI, function (result) {

            $scope.$apply(function () {
                $scope.item = result;
                $scope.item.statusText = issi.statusText;
            });
        });
    };
    $scope.load = function () {
        var config = localStorage.getItem($routeParams.viewName || 'DefaultStatusGrid');
        if (config == null) {
            $scope.config = getDefault();
        } else {
            config = JSON.parse(config || '');
            $scope.config = config;
        }
    }
    $scope.create = function () {

        var viewName = encodeURI($scope.newView.label);
        localStorage.setItem(viewName, JSON.stringify($scope.newView));
        $route.updateParams({ viewName: viewName });
        $scope.config = $scope.newView;
        $(".modal-backdrop").hide();
    }
    $scope.cancel = function () {
        $scope.load();
    };
    $scope.save = function () {
        localStorage.setItem($routeParams.viewName || 'DefaultStatusGrid', JSON.stringify($scope.config));
    };
    $scope.filterFunction = function (element) {
        if ($scope.config.items.length == 0)
            return true;
        return $.inArray(element.ISSI, $scope.config.items) != -1;
    }
    var config = getConfig();
    var websocket = new WebSocket(wsUri + "?MaxAlter=" + config.age);
    websocket.addEventListener("open", function (event) {
        onOpen(event);
    });
    websocket.addEventListener("close", function (event) {
        onClose(event);
    });
    websocket.addEventListener("message", function (event) {
        onMessage(event);
    });
    websocket.addEventListener("error", function (event) {
        onError(event);
    });

    function onOpen(evt) {
        // console.log("Connected. (" + evt + ")");
    }

    function onClose(evt) {
        // console.log("Disconnected. (" + evt + ")");
    }

    function onError(evt) {
        // console.log("Error. (" + evt + ")");
    }

    function onMessage(evt) {
        var data = JSON.parse(evt.data);
        switch (data.type) {
            case 'status':
                // console.log(data);
                for (var i = 0, len = $scope.issis.length; i < len; i++) {
                    var item = $scope.issis[i];
                    if (data.srcSSI + '' == item.ISSI) {
                        $scope.$apply(function () {
                            $scope.issis[i].status = data.status;
                            $scope.issis[i].statusText = data.statusText;
                        });
                        break;
                    }
                }
                break;
        }
    }

    $(function () {
        $scope.load();
        $scope.newView = getDefault();
        $.get("/API/RADIO.JSON", {
            'GerID': "1234"
        }, function (data) {
            $.each(data, function (index, item) {
                $scope.$apply(function () {
                    $scope.radios.push(item);
                    if ($routeParams.radio != null && item.radioID == parseInt($routeParams.radio)) {
                        $scope.data.radio = data;
                    } else if ($scope.data.radio == null) {
                        $scope.data.radio = $scope.radios[0];
                    }
                });
            });
        });
        $.ajax({
            url: '/api/issi.json' + "?MaxAlter=" + config.status,
            type: 'GET',
            success: function (data) {
                $scope.$apply(function () {
                    $scope.issis = data.issis;
                });
            }
        });
    });
});
app.controller('TetraCtrlCfg', function ($scope) {
    $scope.seconds = getConfig();
    $scope.save = function () {
        localStorage.setItem('seconds', JSON.stringify($scope.seconds));
    };
});
app.controller('TetraCtrlSds', function ($scope, $routeParams) {

    $scope.data = { ProtocolID: 130 };
    $scope.data.targetISSI = parseInt($routeParams.ssi);
    $scope.radios = [];
    var config = getConfig();
    var websocket = new WebSocket(wsUri + "?MaxAlter=" + config.age);
    websocket.addEventListener("open", function (event) {
        onOpen(event);
    });
    websocket.addEventListener("close", function (event) {
        onClose(event);
    });
    websocket.addEventListener("message", function (event) {
        onMessage(event);
    });
    websocket.addEventListener("error", function (event) {
        onError(event);
    });

    function onOpen(evt) {
        // console.log("Connected. (" + evt + ")");
    }

    function onClose(evt) {
        // console.log("Disconnected. (" + evt + ")");
    }

    function onError(evt) {
        // console.log("Error. (" + evt + ")");
    }

    function onMessage(evt) {

    }

    $(function () {
        $.get("/API/RADIO.JSON", { 'GerID': "1234" }, function (data) {
            $.each(data, function (index, item) {
                $scope.$apply(function () {
                    $scope.radios.push(item);
                    if ($routeParams.radio != null && item.radioID == parseInt($routeParams.radio)) {
                        $scope.data.radio = item;
                    } else if ($scope.data.radio == null) {
                        $scope.data.radio = $scope.radios[0];
                    }
                });
            });
        });

    });

    $scope.send = function () {
        var message = { text: $scope.data.text, destSSI: $scope.data.targetISSI + '', ProtocolID: $scope.data.ProtocolID, radioID: $scope.data.radio.radioID, type: "sds" };
        websocket.send(JSON.stringify(message));
    }
}
);
app.controller('TetraCtrlMap', function ($scope) {
    var view = localStorage.getItem('map');
    if (view != null) {
        view = JSON.parse(view || '');
        var map = L.map('map').setView(L.latLng(view.lat, view.lng), view.zoom);
    } else {
        var map = L.map('map').setView([51.165, 10.455278], 5);
    }
    $scope.markers = [];
    var config = getConfig();
    var websocket = new WebSocket(wsUri + "?MaxAlter=" + config.age);
    websocket.addEventListener("open", function (event) {
        onOpen(event);
    });
    websocket.addEventListener("close", function (event) {
        onClose(event);
    });
    websocket.addEventListener("message", function (event) {
        onMessage(event);
    });
    websocket.addEventListener("error", function (event) {
        onError(event);
    });

    function onOpen(evt) {
        // console.log("Connected. (" + evt + ")");
    }

    function onClose(evt) {
        // console.log("Disconnected. (" + evt + ")");
    }

    function onError(evt) {
        // console.log("Error. (" + evt + ")");
    }

    function onMessage(evt) {
        // console.log(evt);
        var data = JSON.parse(evt.data);
        data.style = "";
        switch (data.type) {
            case 'status':
                if ($scope.markers[data.srcSSI] != null) {
                    var color = "#08298A";
                    switch (data.status) {
                        case "1":
                            color = "#00FF00";
                            break;
                        case "2":
                            color = "#0AB40A";
                            break;
                        case "3":
                            color = "#FFFF00";
                            break;
                        case "4":
                            color = "#FF0000";
                            break;
                        case "5":
                            color = "#0000FF";
                            break;
                        case "6":
                            color = "#708090";
                            break;
                        case "7":
                            color = "#FF8000";
                            break;
                        case "8":
                            color = "#FF0080";
                            break;
                    }
                    var icon = L.MakiMarkers.icon({ size: "m", icon: data.status, color: color });

                    $scope.markers[data.srcSSI].setIcon(icon);
                }
                break;
            case 'call':
            case 'radio':
            case 'devupd':
            case 'sds':
                break;
            case 'pos':
                // console.log(data);
                if ($scope.markers[data.srcSSI] == null) {
                    $scope.markers[data.srcSSI] = L.marker([data.Lat, data.Lon]).bindTooltip(data.srcName, { permanent: true, opacity: 0.7 }).addTo(map).bindPopup('<B>' + data.srcName + '</B><BR>' + data.srcSSI + '<BR>Position: ' + ToJavaScriptDate(data.ts).toLocaleTimeString("de-DE") + ' ' + ToJavaScriptDate(data.ts).toLocaleDateString("de-DE"));
                } else {
                    $scope.markers[data.srcSSI] = $scope.markers[data.srcSSI].setLatLng([data.Lat, data.Lon]).bindPopup('<B>' + data.srcName + '</B><BR>' + data.srcSSI + '<BR>Position: ' + ToJavaScriptDate(data.ts).toLocaleTimeString("de-DE") + ' ' + ToJavaScriptDate(data.ts).toLocaleDateString("de-DE"));
                }
                break;
            default:
                console.error("Unexpected message recieved");
                break;
        }
    }
    function saveMap(e) {
        var view = {
            lat: map.getCenter().lat,
            lng: map.getCenter().lng,
            zoom: map.getZoom()
        };
        localStorage.setItem('map', JSON.stringify(view));
    }
    map.on('moveend', saveMap);
    map.on('zoomend', saveMap);

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

    $(function () {
        var config = getConfig();
        $.ajax({
            url: '/api/statusgps.json?maxalterstatus=' + config.age + '&maxalterpos=' + config.gps,
            type: 'GET',
            success: function (data) {
                $.each(data.issis, function (index, item) {
                    if ($scope.markers[item.ISSI] == null) {
                        $scope.markers[item.ISSI] = L.marker([item.Lat, item.Lon]).bindTooltip(item.name, { permanent: true, opacity: 0.7 }).addTo(map).bindPopup('<B>' + item.name + '</B><BR>' + item.OPTA + '<BR>Status: ' + ToJavaScriptDate(item.statusTS).toLocaleTimeString("de-DE") + ' ' + ToJavaScriptDate(item.statusTS).toLocaleDateString("de-DE") + '<BR>Position: ' + ToJavaScriptDate(item.posTS).toLocaleTimeString("de-DE") + ' ' + ToJavaScriptDate(item.posTS).toLocaleDateString("de-DE"));
                    } else {
                        $scope.markers[item.ISSI] = $scope.markers[item.ISSI].setLatLng([item.Lat, item.Lon]).bindPopup('<B>' + item.name + '</B><BR>' + item.OPTA + '<BR>Status: ' + ToJavaScriptDate(item.statusTS).toLocaleTimeString("de-DE") + ' ' + ToJavaScriptDate(item.statusTS).toLocaleDateString("de-DE") + '<BR>Position: ' + ToJavaScriptDate(item.posTS).toLocaleTimeString("de-DE") + ' ' + ToJavaScriptDate(item.posTS).toLocaleDateString("de-DE"));
                    }
                    if (item.status == "8003") item.status = "1";
                    if (item.status == "8004") item.status = "2";
                    if (item.status == "8005") item.status = "3";
                    if (item.status == "8006") item.status = "4";
                    if (item.status == "8008") item.status = "6";
                    if (item.status == "8009") item.status = "7";
                    if (item.status == "800A") item.status = "8";

                    var color = "#08298A";
                    switch (item.status) {
                        case "1":
                            color = "#00FF00";
                            break;
                        case "2":
                            color = "#0AB40A";
                            break;
                        case "3":
                            color = "#FFFF00";
                            break;
                        case "4":
                            color = "#FF0000";
                            break;
                        case "5":
                            color = "#0000FF";
                            break;
                        case "6":
                            color = "#708090";
                            break;
                        case "7":
                            color = "#FF8000";
                            break;
                        case "8":
                            color = "#FF0080";
                            break;
                        default:
                            item.status = "";
                    }
                    var icon = L.MakiMarkers.icon({ size: "m", icon: item.status, color: color });
                    if (item.status != "") $scope.markers[item.ISSI].setIcon(icon);
                });
            }
        });
    });
}
);
app.controller('TetraCtrlStatus', function ($scope) {
    $scope.sortType = 'name';
    $scope.sortReverse = false;
    $scope.searchNeedle = '';
    $scope.order = function (sortType) {
        $scope.sortReverse = ($scope.sortType === sortType) ? !$scope.sortReverse : false;
        $scope.sortType = sortType;
    };
    $scope.datas = [];
    var config = getConfig();
    var websocket = new WebSocket(wsUri + "?MaxAlter=" + config.age);
    websocket.addEventListener("message", function (event) {
        onMessage(event);
    });

    function onMessage(evt) {
        var data = JSON.parse(evt.data);
        data.style = "";
        switch (data.type) {
            case 'status':
                parseStatus(data);
                break;
            case 'call':
            case 'pos':
            case 'sds':
            case 'devupd':
            case 'radio':
                break;
            default:
                console.error("Unexpected message recieved");
                break;
        }
    }

    function parseStatus(data) {
        data.style = "status-" + data.status;
        data.status = data.statusText;
        data.name = data.srcName;
        data.time = window.ToJavaScriptDate(data.ts);
        $scope.$apply(function () {
            for (var i = 0, len = $scope.datas.length; i < len; i++) {
                var entry = $scope.datas[i];
                if (entry.srcSSI == data.srcSSI) {
                    $scope.datas[i] = data;
                    return;
                }
            }
            $scope.datas.unshift(data);
        });
    }
});
app.controller('TetraCtrlLive', function ($scope) {
    $scope.typefilter = {
        sds: true,
        status: true,
        call: true,
        callout: true
    };
    $scope.datas = [];
    var config = getConfig();
    var websocket = new WebSocket(wsUri + "?MaxAlter=" + config.age);
    websocket.addEventListener("open", function (event) {
        onOpen(event);
    });
    websocket.addEventListener("close", function (event) {
        onClose(event);
    });
    websocket.addEventListener("message", function (event) {
        onMessage(event);
    });
    websocket.addEventListener("error", function (event) {
        onError(event);
    });

    $scope.toggleFilter = function (event, value) {
        if ($(event.currentTarget).hasClass("checked")) {
            $(event.currentTarget).removeClass("checked");
            $(event.currentTarget).addClass("unchecked");
        }
        else {
            $(event.currentTarget).addClass("checked");
            $(event.currentTarget).removeClass("unchecked");
        }
        setTimeout(function () {
            $scope.$apply(function () {
                switch (value) {
                    case 'sds':
                        $scope.typefilter.sds = !$scope.typefilter.sds;
                        break;
                    case 'call':
                        $scope.typefilter.call = !$scope.typefilter.call;
                        break;
                    case 'status':
                        $scope.typefilter.status = !$scope.typefilter.status;
                        break;
                    case 'callout':
                        $scope.typefilter.callout = !$scope.typefilter.callout;
                        break;
                }
            });
        }, 50);

    }

    function onOpen(evt) {
        // console.log("Connected. (" + evt + ")");
    }

    function onClose(evt) {
        // console.log("Disconnected. (" + evt + ")");
    }

    function onError(evt) {
        // console.log("Error. (" + evt + ")");
    }

    function onMessage(evt) {
        var data = JSON.parse(evt.data);
        data.style = "";
        switch (data.type) {
            case 'call':
                parseCall(data);
                break;
            case 'status':
                parseStatus(data);
                break;
            case 'pos':
                parsePos(data);
                break;
            case 'sds':
                parseSds(data);
                break;
            case 'callout':
                parseAlarm(data);
                break;
            case 'devupd':
                break;
            case 'radio':
                break;
            default:
                console.error("Unexpected message recieved");
                break;
        }
    }

    function parseStatus(data) {
        data.style = "status-" + data.status;
        data.readableType = "Status";
        data.message = data.statusText;
        data.dur = "Stat";
        data.timestamp = window.ToJavaScriptDate(data.ts);
        $scope.$apply(function () {
            $scope.datas.unshift(data);
        });
    }

    function parseSds(data) {
        data.readableType = "SDS";
        data.message = data.text;
        data.dur = "SDS";
        data.timestamp = window.ToJavaScriptDate(data.ts);
        $scope.$apply(function () {
            $scope.datas.unshift(data);
        });
    }

    function parseCall(data) {
        data.timestamp = window.ToJavaScriptDate(data.tsStart);
        data.end = window.ToJavaScriptDate(data.tsEnd);
        if (data.end != null)
            data.dur = data.end - data.timestamp;
        switch (data.callType) {
            case 0:
                data.readableType = "Einzelruf";
                data.destName = "Einzelruf";
                data.message = "Eingehender Einzelruf";
                data.dur = "von";
                break;
            default:
                data.readableType = "Gespräch";
                data.message = data.srcOPTA;
                break;
        }
        $scope.$apply(function () {
            for (var i = 0, len = $scope.datas.length; i < len; i++) {
                var entry = $scope.datas[i];
                if (entry.type == 'call' && entry.ID == data.ID) {
                    $scope.datas[i] = data;
                    return;
                }
            }
            $scope.datas.unshift(data);
        });
    }

    function parsePos(data) {

    }

    function parseAlarm(data) {
        data.readableType = "Alarm";
        data.timestamp = window.ToJavaScriptDate(data.ts);

        data.radioName = data.radioName;
        data.destName = data.destName;

        data.dur = '' + data.responseYes + ' / ' + data.responseNO;

        data.srcName = data.srcName;

        data.message = data.text;

        data.style = "severity-" + data.severityNum;


        $scope.$apply(function () {
            // update data in the list
            for (var i = 0, len = $scope.datas.length; i < len; i++) {
                var entry = $scope.datas[i];
                if (entry.type == 'callout' && entry.ID == data.ID) {
                    $scope.datas[i] = data;
                    return;
                }
            }
            // otherwise prepend data 
            $scope.datas.unshift(data);
        });
    }
}
);
