function DataVM() {
    "use strict";
    var self = this;
    self.helpers = new Helpers();
    self.menuOptions = ["Home"];
    self.possibleLogDirections = ko.observableArray([
        { Text: "In", value: 1 },
        { Text: "Out", value: 2 }
    ]),
    self.chosenMenuItemId = ko.observable();
    self.appDetails = ko.observable(null);
    self.userList = ko.observable(null);
    self.groupsList = ko.observable(null);
    self.chosenUserDetails = ko.observable(null);
    self.userTimeLogData = ko.observable(null);
    self.unassignedCardData = ko.observable(null);
    self.chosenTimeLogUserId = -1;
    self.selectedTimeLogDate = ko.observable(null);
    self.selectedCalendarWeek = ko.observable(0);
    self.errorData = ko.observable(null);
    self.manualLog = ko.observable(null);
    self.apiEndpoints = {
        root: "http://localhost:8800",
        getUserList: "/api/users",
        getUserDetails: "/api/users",
        editUser: "/api/users/edit",
        getTimeLogs: "/api/timelogs",
        getUnassignedCards: "/api/cards/unassigned",
        getGroups: "/api/groups",
        getAppDetails: "/api/app",
        manualLogsCreate: "/api/logs/create",
        manualLogsDelete: "/api/logs/delete"
    };
    self.uiPages = {
        users: "users",
        userDetails: "userData",
        timeLogs: "timelogs",
        home: function () { return this.users; }
    };
    self.goToMenuOption = function (menu) { location.hash = menu; console.log("goToMenuOption: " + menu); };
    self.goToUserDetails = function (user) { location.hash = self.uiPages.userDetails + "/" + user.UserId; };
    self.goToTimeLogs = function (user, data, args) {
        var userId;
        if (user.UserId) {
            userId = user.UserId;
        } else {
            userId = user;
        }
        var url = "timelogs" + "/" + userId;
        if (args) {
            url = self.helpers.createRequestUrl(url, args, false, false);
        }
        location.hash = url;
    };
    self.assignErrorObject = function(errCode, errMessage, errorSource) {
        var errDat = {
            errorCode: errCode,
            errorMessage: errMessage,
            errorSource: errorSource,
            errorDate: new Date().toDateString("yyyy-mm-dd")
        };
        self.errorData(errDat);
    }
    self.returnButtonClick = function (data, event) {
        var destination = self.helpers.getPageDestination(data, event);
        if (destination !== "") {
            self.goToMenuOption(destination); //redirect to whereever the button is telling us to go..
        }
    };
    self.convertToHours = function (value) {
        var hrs = value / 60;
        if (hrs < 1) {
            return value + " mins";
        }
        var h = Math.floor(hrs);
        var m = Math.floor((hrs % 1) * 60);
        return h + " hrs " + m + " minutes";
    };
    self.convertToDisplayTime = function (dateValue) {
        var date = new Date(dateValue);
        return date.getHours() + ":" + self.padNumber(date.getMinutes());
    };
    self.correctLogOffset = function(logCount) {
        if (logCount % 2 !== 0) {
            logCount += 1;
        }
        return logCount;
    };
    self.round = function(value, decimals) {
        return parseFloat(Math.round(value * 100) / 100).toFixed(decimals);
    };
    self.getTimeLogEntryArrayLength = function(maxDailyLogs) {
        return Math.round(maxDailyLogs/2);
    };
    self.padNumber = function(number) {
        return (number < 10 ? "0" : "") + number;
    };
    self.convertToDisplayDateTime = function (dateValue) {
        var date = new Date(dateValue); // dd MM YY HH:mm:ss e.g.: 01 Mar 17 17:34:02
        return date.getDate() + " "
            + date.toLocaleString("en-us", { month: "long" }) + " "
            + (date.getYear()-100) + "  "
            + self.padNumber(date.getHours()) + ":"
            + self.padNumber(date.getMinutes()) + ":"
            + self.padNumber(date.getSeconds());
    };
    self.dismissAlert = function(data, event) {
        self.errorData(null);
    };
    self.setPageSize = function(data) {
        if (self.userList().PageSize !== data && self.userList().PageSize !== -1) {
            self.setPagination(data, 1);
        }
    };
    self.goToUserPage = function (data) {
        if (self.userList().PageNumber !== data && self.userList().PageNumber !== -1) {
            self.setPagination(self.userList().PageSize, data);
        }
    };
    self.getCurrentGroupFilter = function() {
        if (self.userList() !== null) {
            if (self.userList().GroupFilter !== null) {
                return self.userList().GroupFilter.Name;
            }
        }
        return "";
    };
    self.clearGroupFilter = function () {
        self.setPagination(20, 1);
    };
    self.hasGroupFilter = function() {
        if(self.userList() !== null)
            if (self.userList().GroupFilter)
                return true;
        return false;
    };
    self.hasQuery = function() {
        if (self.userList() !== null) {
            if (self.userList().Query && self.userList().Query !== "")
                return true;
        }
        return false;
    };
    self.groupFilter = function(data) {
        console.log("filter by group: " + data);
        var args = [
            {
                key: "groupId",
                value: data
            }
        ];
        var url = self.helpers.createRequestUrl("users", args, false, false);
        location.hash = url;
        console.log(url);
    };
    self.setPagination = function(pageSize, pageNumber) {
        var args = [
            {
                key: "pageSize",
                value: pageSize
            },
            {
                key: "pageNumber",
                value: pageNumber
            }
        ];
        var url = self.helpers.createRequestUrl("users", args, false, false);
        location.hash = url;
        console.log(url);
    };
    self.initDatePicker = function (selectedDate) {
        if (!selectedDate) {
            selectedDate = new Date();
        } else {
            selectedDate = new Date(selectedDate);
        }
        moment.locale("en", { week: { dow: 1 } });
        $("#weeklyDatePicker").datetimepicker({
            format: "DD/MM/YYYY",
            inline: true,
            showTodayButton: true,
            calendarWeeks: true,
            maxDate: "now",
            date: selectedDate
        });
    };
    self.assignHandler = function() {
        var elem = $("#weeklyDatePicker")[0];
        var data = jQuery.hasData(elem) && jQuery._data(elem);
        if (!data.events) {
            $("#weeklyDatePicker")
                .on("dp.change",
                    function(e) {
                        var value = e.date;
                        self.selectedCalendarWeek(moment(value).isoWeek());
                        self.goToTimeLogs(self.chosenTimeLogUserId,
                            null,
                            [{ key: "selectedDate", value: moment(value).format("MM-DD-YYYY") }]);
                    });
        }
    };
    self.assignUpdateHandler = function() {
        var elem = $("#datetimepicker1")[0];
        var data = jQuery.hasData(elem) && jQuery._data(elem);
        if (!data.events) {
            $("#datetimepicker1")
                .on("dp.change",
                    function(e) {
                        var value = e.date.toISOString();
                        self.manualLog().EventTime = value;
                    });
        }
    };
    self.getUserList = function (pageSize, pageNumber, groupId) {
        var args = null;
        if (pageSize && pageNumber) {
            args = [
                {
                    key: "pageSize",
                    value: pageSize
                },
                {
                    key: "pageNumber",
                    value: pageNumber
                }
            ];
        } else if(groupId) {
            args = [
            {
                key: "groupId",
                value: groupId
            }];
        }
        var url = self.helpers.createRequestUrl(self.apiEndpoints.getUserList, args, false);
        $.getJSON(url, function (res) {
            self.userList(res);
            $('[data-toggle="tooltip"]').tooltip();
        }).fail(function (response, status, error) {
            console.log("error - getusers");
            var errObj = self.helpers.processRequestFailure(response, status, error);
            self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "getUserList");
        });
    };
    self.getAppDetails = function() {
        var url = self.helpers.createRequestUrl(self.apiEndpoints.getAppDetails, null, false, false);
        $.getJSON(url, function (res) {
            self.appDetails(res);
        }).fail(function (response, status, error) {
            console.log("error - getusers");
            var errObj = self.helpers.processRequestFailure(response, status, error);
            self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "getUserList");
        });
    };
    self.searchUsers = function(query) {
        var url = self.helpers.createRequestUrl(self.apiEndpoints.getUserList,
            [{ key: "query", value: query }], false, false);
        $.getJSON(url,
            function(res) {
                self.userList(res);
            }).fail(function(resp, status, error) {
                self.goToMenuOption(self.uiPages.home());
                var errObj = self.helpers.processRequestFailure(resp, status, error);
                self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "searchUsers");
            }
        );
    };
    self.getUserDetails = function (userId) {
        var url = self.helpers.createRequestUrl(self.apiEndpoints.getUserDetails + "/" + userId, null, false);
        $.getJSON(url, function (res) {
            self.chosenUserDetails(res);
        }).fail(function (resp, status, error) {
            console.log("error - getuserdetails");
            var errObj = self.helpers.processRequestFailure(resp, status, error);
            self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "getUserDetails");
            self.goToMenuOption(self.uiPages.home());
        });
    };
    self.submitChangedUser = function (user) {
        var url = self.helpers.createRequestUrl(self.apiEndpoints.editUser, null, false, false);
        $.post(url, user, function () {
        }, "json")
        .done(function () {
            self.chosenUserDetails(null);
            self.goToMenuOption(self.uiPages.home());
        })
        .fail(function (resp, status, error) {
            var errObj = self.helpers.processRequestFailure(resp, status, error);
            self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "submitChangedUser");
            self.chosenUserDetails(null);
            self.goToMenuOption(self.uiPages.home());
        });
    };
    self.getTimeLogData = function (userId, selectedDate) {
        var urlArgs = [{ key: "userId", value: userId }];
        if (selectedDate) {
            urlArgs.push({ key: "selectedDate", value: selectedDate });
        }
        var url = self.helpers.createRequestUrl(self.apiEndpoints.getTimeLogs,
            urlArgs,
            false);
        $.getJSON(url, function (res) {
            self.userTimeLogData(res);
            self.initDatePicker(res.SelectedDate);
            self.assignHandler();
        }).fail(function (resp, status, error) {
            console.log("error - getuserdetails");
            var errObj = self.helpers.processRequestFailure(resp, status, error);
            self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "getTimeLogData");
            self.goToMenuOption(self.uiPages.home());   //go home.
        });
    };
    self.getUnassignedCardData = function () {
        var url = self.helpers.createRequestUrl(self.apiEndpoints.getUnassignedCards, null, false);
        $.getJSON(url, function (res) {
            self.unassignedCardData(res);
        }).fail(function (resp, status, error) {
            console.log("error - getuserdetails");
            var errObj = self.helpers.processRequestFailure(resp, status, error);
            self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "getUnassignedCardData");
        });
    };
    self.getGroups = function (successFunc) {
        var url = self.helpers.createRequestUrl(self.apiEndpoints.getGroups, null, false);
        return $.getJSON(url, function (res) {
            successFunc(res);
            //self.chosenUserDetails().Groups = res;
            //self.chosenUserDetails.valueHasMutated();
        }).fail(function (resp, status, error) {
            console.log("error - getGroups");
            var errObj = self.helpers.processRequestFailure(resp, status, error);
            self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "getGroups");
        });
    };
    self.createManualLog = function(newLog) {
        var url = self.helpers.createRequestUrl(self.apiEndpoints.manualLogsCreate, null, false, false);
        $.post(url, newLog, function () {
        }, "json")
        .done(function () {
            self.manualLog(null);
            $('#manualLogDialog').modal("hide");
            self.goToMenuOption(self.uiPages.home());
        })
        .fail(function (resp, status, error) {
            var errObj = self.helpers.processRequestFailure(resp, status, error);
            self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "createManualLog");
            self.chosenUserDetails(null);
            self.goToMenuOption(self.uiPages.home());
        });
    };
    self.deleteManualLog = function (logToDelete) {
        var url = self.helpers.createRequestUrl(self.apiEndpoints.manualLogsDelete, null, false, false);
        $.ajax({
            url: url,
            type: "DELETE",
            data: logToDelete,
            success: function (result) {
                console.log("successfully deleted .." + result);
                self.goToMenuOption(self.uiPages.home());
            }
        });
    };
    self.createContextMenu = ko.observableArray([
        { text: "Create", action: createlog }
    ]);
    self.editContextMenu = ko.observableArray([
        { text: "Create", action: createlog },
        { text: "Edit", action: editlog },
        { text: "Delete", action: deleteLog }
    ]);
    function editlog (data) {
        self.manualLog(data);
        $('#manualLogDialog').modal("show");
        $('#datetimepicker1').datetimepicker({
            format: "YYYY-DD-MM HH:mm:ss",
            date: new Date(data.EventTime),
            minDate: moment(new Date(data.EventTime)).startOf('week'),
            maxDate: moment(new Date(data.EventTime)).endOf('week')
        });
        self.assignUpdateHandler();
    };
    function createlog(data) {
        self.manualLog({
            CalendarWeek:-1,
            Direction:-1,
            EventTime: new Date().toISOString(),
            Id: -1,
            IdentifierId: -1,
            UserId: self.chosenTimeLogUserId,
            Year: 0
        });
        $('#manualLogDialog').modal("show");
        $('#datetimepicker1').datetimepicker({
            format: "YYYY-DD-MM HH:mm:ss",
            minDate: moment(self.selectedTimeLogDate()).startOf("week"),
            maxDate: moment(self.selectedTimeLogDate()).endOf("week")
        });
        self.assignUpdateHandler();
    };
    function deleteLog(data) {
        if (confirm("Are you sure you want to delete this log?")) {
            self.deleteManualLog(data);
        }
    };
    Sammy(function () {
        this.get("#users", function () {
            var query = this.params.query;
            var pageSize = this.params.pageSize;
            var pageNumber = this.params.pageNumber;
            var groupId = this.params.groupId;
            self.chosenMenuItemId("Home");
            self.groupsList(null);
            self.chosenUserDetails(null);
            self.userList(null);
            self.userTimeLogData(null);
            self.manualLog(null);
            if (self.appDetails() === null) {
                self.getAppDetails();
            }
            self.getGroups(function (data) { self.groupsList(data); });
            if (query)
                self.searchUsers(query);
            else if (groupId && groupId > 0)
                self.getUserList(null, null, groupId);
            else
                self.getUserList(pageSize, pageNumber);
        });
        this.get("#userData/:userId", function () {
            self.chosenMenuItemId("Data");
            self.groupsList(null);
            self.chosenUserDetails(null);
            self.userList(null);
            self.userTimeLogData(null);
            self.manualLog(null);
            self.getUserDetails(this.params.userId);
            self.getUnassignedCardData();
        });
        this.get("#timelogs/:userId", function () {
            if (this.params.selectedDate) {
                self.selectedTimeLogDate(this.params.selectedDate);
            } else {
                self.selectedTimeLogDate(new Date());
            }
            self.chosenTimeLogUserId = this.params.userId;
            self.chosenMenuItemId("Other");
            self.groupsList(null);
            self.chosenUserDetails(null);
            self.userList(null);
            self.userTimeLogData(null);
            self.manualLog(null);
            self.getTimeLogData(this.params.userId, self.selectedTimeLogDate());
        });
        this.get("#newUser", function () {
            self.chosenMenuItemId("newUser");
            self.userList(null);
            self.userTimeLogData(null);
            self.chosenUserDetails({
                "UserId": -1,
                "FirstName": null,
                "LastName": null,
                "HoursPerWeek": null,
                "AssociatedIdentifiers": [],
                "Groups": [],
                "IsContractor": false
            });
            self.getGroups(function(data) {
                self.chosenUserDetails().Groups = data;
                self.chosenUserDetails.valueHasMutated();
            });
            self.getUnassignedCardData();
        });
        this.get("#stats", function () {
            self.goToMenuOption("users");
        });
        this.post("#edituser", function () {
            $.each(self.chosenUserDetails().AssociatedIdentifiers,
                function (k, v) {
                    if (v.IsAssociatedToUser !== true) {
                        self.chosenUserDetails().AssociatedIdentifiers.splice(k, 1);
                    }
                });
            $.each(self.unassignedCardData().data, function (k, v) {
                if (v.IsAssociatedToUser === true) {
                    self.chosenUserDetails().AssociatedIdentifiers.push(v);
                }
            });
            self.submitChangedUser(self.chosenUserDetails());
            return false;
        });
        this.post("#manualLog",
            function() {
                self.createManualLog(self.manualLog());

                $('#manualLogDialog').modal("hide");
                //self.goToTimeLogs(self.chosenTimeLogUserId, null, [{ key: "selectedDate", value: self.selectedTimeLogDate() }]);
            });
        //default route (home page)
        this.get("", function () { this.app.runRoute("get", "#" + self.uiPages.home()) });
    }).run();
};
ko.applyBindings(new DataVM());
//$(document).on("mouseenter", ".datepicker-days tbody tr", function () {
//    $(this).addClass("highlight");
//});
//$(document).on("mouseleave", ".datepicker-days tbody tr", function () {
//    $(this).removeClass("highlight");
//});