var rwthapp = rwthapp || {};
rwthapp.util = rwthapp.util || {};

rwthapp.util.backButtonHook;
rwthapp.util.orientationChangeHook;

rwthapp.util.isLandscapeState;

rwthapp.util.initNamespace = function (namespace) {
    /// <deprecated type="deprecate" >usage of this method breaks code completion in Visual Studio.</deprecated>
    var parts = namespace.split(".");

    var current = rwthapp;

    for (var i = 0; i < parts.length; i++) {

        if (!current[parts[i]]) {

            current[parts[i]] = {};
        }

        current = current[parts[i]];
    }
};

rwthapp.util.initAppOrientationBehavior = function () {

    // when using tablet all orientations are allowed
    if (rwthapp.platformInfo.isTablet()) {

        screen.unlockOrientation();
    }
    else {

        // smartphones should be used in portrait orientation only
        screen.lockOrientation('portrait');
    }

    if (rwthapp.util.isLandscape()) {

        if ($('.my-slide-nav').navdrawer('smallDeviceSupport')) {

            rwthapp.templates.menu.activateSevenInchLock(true);
        }
    }

    var menuPinned = rwthapp.templates.menu.isMenuPinned();

    if (menuPinned !== null) {

        $('.my-slide-nav').navdrawer('lockAlwaysVisible', !menuPinned);
        rwthapp.templates.menu.setMenuPinned(menuPinned);
    }
};

rwthapp.util.changeOrientationOnTablet = function () {

    if (this.isFunction(this.orientationChangeHook)) {

        this.orientationChangeHook();
    }

    if ($('#content .rwth-tablet').length > 0) {

        var large = $('#content .rwth-tablet').data("large"), small = $('#content .rwth-tablet').data("small");

        if (this.isLandscapeState) {

            $('#content_left').removeAttr("class");
            $('#content_right').removeAttr("class");
            $('#content_left').css('display', '');
            $('#content_right').css('display', '');
            $('#content_right').css('padding', '');
            $('#content_left').css('padding', '');

            if ($('#content_left').data("leftlarger")) {

                $('#content_left').addClass('col ' + large);
                $('#content_right').addClass('col ' + small);

                return;
            }

            $('#content_left').addClass('col ' + small);
            $('#content_right').addClass('col ' + large);
        }
        else {

            $('#content_right').css('padding', '0');
            $('#content_left').css('padding', '0');

            if ($('#content_left').data('tplleft') === rwthapp.navigator.currentPage.target.renderedTemplate) {

                $('#content_left').addClass('col s12');
                $('#content_right').css('display', 'none');
                $('#content_left').css('display', '');
            }

            if ($('#content_right').data('tplright') === rwthapp.navigator.currentPage.target.renderedTemplate) {

                $('#content_right').addClass('col s12');
                $('#content_left').css('display', 'none');
                $('#content_right').css('display', '');
            }
        }
    }
};

rwthapp.util.generateRandomId = function (length) {
	var id = "",
		chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
	while (length--) {
		id += chars.charAt(Math.random() * chars.length);
	}
	return id;
};

rwthapp.util.isFunction = function(obj) {

    return !!(obj && obj.constructor && obj.call && obj.apply);
}

rwthapp.util.backButtonClicked = function () {

    if (this.isFunction(this.backButtonHook)) {

        var proceed = this.backButtonHook();

        if (!proceed) {

            return;
        }
    }

    if ($('.my-slide-nav').css("transform") === 'matrix(1, 0, 0, 1, 300, 0)') {

        if (rwthapp.templates.menu.state.submenuOpen) {

            rwthapp.templates.menu.initMainMenu();
        }
        else if (rwthapp.templates.menu.state.menuCloseable) {

            rwthapp.templates.menu.state.menuCloseable = false;
            $('.my-slide-nav').navdrawer('close');
        }

        return;
    }
    else if (rwthapp.templates.menu.isMenuPinned() && rwthapp.templates.menu.state.submenuOpen) {
        
        rwthapp.templates.menu.initMainMenu();
        return;
    }

    // Check if a modal is open
    if ($("#modal:visible").length) {
        $("#modal").closeModal();
    }
    // Backbutton can be used to exit app on Windows Phone and Android
    else if ((location.hash === '' || rwthapp.navigator.currentPage.target.parameters._homescreen === "true") && rwthapp.platformInfo.shouldExitOnBack()) {
        rwthapp.util.exitApp();
        return;
    }
    else {

        rwthapp.navigator.goBack();
    }
};

rwthapp.util.addRightFeatureSpecificButtonToNavbar = function (id, icon, clickFunction) {

    if ($('#' + id).length === 0) {

        $('#feature').append('<a id="' + id + '" class="button-collapse"><i class="material-icons">' + icon + '</i></a>');

        $('#' + id).click(clickFunction);
        // Perform postprocessing (fixing icons, removing waves effect) if necessary
        rwthapp.templateRenderer.performPostprocessing();
    }
};

rwthapp.util.removeRightFeatureSpecificButtonFromNavbar = function (id) {

    $('#' + id).remove();
};

rwthapp.util.setFavoriteState = function (route) {

    $('#favoriteLink').remove();

    if (rwthapp.favorites.isFavoriteAlreadySet(route)) {

        $('#favorite').append('<a id="favoriteLink" class="button-collapse"><i class="material-icons">star</i></a>');
    }
    else {

        $('#favorite').append('<a id="favoriteLink" class="button-collapse"><i class="material-icons">star_border</i></a>');
    }

    // Perform postprocessing (fixing icons, removing waves effect) if necessary
    rwthapp.templateRenderer.performPostprocessing();

    $('#favoriteLink').click(function () {

        var hash = rwthapp.navigator.currentPage.target.hash;

        if (rwthapp.favorites.isFavoriteAlreadySet(hash)) {

            rwthapp.favorites.removeRWTHFavorite(hash);
        }
        else {

            var subTitle = rwthapp.navigator.currentPage.navTitle.subTitle;

            rwthapp.favorites.createRWTHFavorite(hash, rwthapp.navigator.currentPage.navTitle.title + (subTitle !== '' ? (' - ' + subTitle) : ''));
        }

        rwthapp.templates.menu.initMenu();

        rwthapp.util.setFavoriteState(hash);
    });
};

rwthapp.util.isLandscape = function () {

    if (this.isLandscapeState === undefined) {

        if (rwthapp.platformInfo.isIOS()) {

            if (screen.orientation === 'landscape-primary' || screen.orientation === 'landscape-secondary') {

                this.isLandscapeState = true;
            }
            else {

                this.isLandscapeState = false;
            }
        }
        else if(rwthapp.platformInfo.isAndroid()) {

            if (screen.orientation.type !== undefined) {

                if (screen.orientation.type === 'landscape-primary' || screen.orientation.type === 'landscape-secondary') {

                    this.isLandscapeState = true;
                }
                else {

                    this.isLandscapeState = false;
                }
            }
            else {
            
                // fallback for android versions pre 5.0 where screen.orientation is inverted for some reason
                if ($(window).height() < $(window).width()) {

                        this.isLandscapeState = true;
                }
                else {
                    
                    this.isLandscapeState = false;
                }
            }
        }
        else if(rwthapp.platformInfo.isWindowsUniversal() || rwthapp.platformInfo.isWP8()) {

            if (screen.msOrientation === 'landscape-primary' || screen.msOrientation === 'landscape-secondary') {

                this.isLandscapeState = true;
            }
            else {

                this.isLandscapeState = false;
            }
        }
    }

    return this.isLandscapeState;
};

rwthapp.util.changeOrientationState = function () {

    if (this.isLandscapeState === undefined) {

        this.isLandscape();
    }

    this.isLandscapeState = !this.isLandscapeState;

    return this.isLandscapeState;
}

rwthapp.util.versionCompare = function (v1, v2) {
    var v1Array = v1.split('.');
    var v2Array = v2.split('.');

    var versionLength = Math.max(v1Array.length, v2Array.length);

    while (v1Array.length < versionLength) v1Array.push("0");
    while (v2Array.length < versionLength) v2Array.push("0");

    for (var i = 0; i < versionLength; i++) {
        var v1Digit = parseInt(v1Array[i], 10) || 0; // NaN is treated as 0
        var v2Digit = parseInt(v2Array[i], 10) || 0;

        if (v1Digit > v2Digit) {
            return 1;
        } else if (v1Digit < v2Digit) {
            return -1;
        }
    }

    return 0;
};

rwthapp.util.unsafeFunction = function (f) {
    /// <summary>Wrapper for MSApp.execUnsafeLocalFunction to execute potentially unsafe code on windows universal</summary>
    /// <param name="f">function to be executed</param>
    if (typeof f === 'function') {
        if (rwthapp.platformInfo.isWindowsUniversal()) {
            MSApp.execUnsafeLocalFunction(f);
        } else {
            f();
        }
    }
};

rwthapp.util.getPropertyByString = function (obj, propertyString) {
	propertyString = propertyString.replace(/\[(\w+)\]/g, '.$1'); // Convert indices to properties
	propertyString = propertyString.replace(/^\./, '');           // Strip a leading dot
	var properties = propertyString.split('.');
	while (properties.length > 0) {
		var property = properties.shift(); // Take first property
		if (property in obj) {
			obj = obj[property];
		} else {
			return;
		}
	}
	return obj;
};

rwthapp.util.vibrate = function (duration) {
    if (rwthapp.options.vibration.isEnabled()) {
        if (duration === undefined) {
            duration = 1000;
        }
        navigator.vibrate(duration);
    }
};

rwthapp.util.passwordPrompt = function (message) {
    return new Promise(function (resolve) {
        var modalInit = function () {
            $("#modal-button-confirm").on("click", function () {
                var password = $("#passwordInput").val();
                resolve(password);
            });

            $("#passwordInput").on("keyup", function (e) {
                if (e.which === 13) {
                    $("#modal-button-confirm").trigger("click");
                }
            });
        };

        rwthapp.modal.createModal(modalInit, "modal.passwordPrompt", {
            promptText: message
        }).then(function () {
            // If modal closes without clicking ok button, resolve without password
            resolve();
        });
    });
};

rwthapp.util.showKeyboard = function () {
    // Use plugin to show keyboard (only compatible with android and windows)
    if (!rwthapp.platformInfo.isRipple() && (rwthapp.platformInfo.isAndroid() || rwthapp.platformInfo.isWindowsUniversal())) {
        cordova.plugins.Keyboard.show();
    }
};

rwthapp.util.closeKeyboard = function () {
    // Use plugin to close keyboard (compatible with android, ios and windows)
    if (!rwthapp.platformInfo.isRipple() && (rwthapp.platformInfo.isAndroid() || rwthapp.platformInfo.isWindowsUniversal() || rwthapp.platformInfo.isIOS())) {
        cordova.plugins.Keyboard.close();
    }
};

rwthapp.util.fixPhoneFormat = function(phoneNumber){
    //At the moment, the problem just occurs on iOS-Devices
    if (phoneNumber && rwthapp.platformInfo.isIOS()) {
        phoneNumber = phoneNumber.split(" ").join("-");
    }
    return phoneNumber;
}

rwthapp.util.showLoadingScreen = function () {

    if (rwthapp.platformInfo.hasAnimationHideBug() || $('#overlay').children().length === 0) {

        this.showLoadingScreenInSpecificDiv($('#overlay'));
    } 
    $('#overlay').show();
};

rwthapp.util.showLoadingScreenInSpecificDiv = function (targetContainer, data) {

    rwthapp.templateRenderer.render(targetContainer, 'loadingAnimation', data);
}

rwthapp.util.hideLoadingScreen = function () {
    $('#overlay').hide();
};

rwthapp.util.exitApp = function () {
    navigator.app.exitApp();
};

rwthapp.util.isCarnival = function () {
    // 11.11.15 11:11:11 - 11.11.15 23:59:59
    var firstDayStart = new Date(2015, 10, 11, 11, 11, 11).getTime();
    var firstDayEnd = new Date(2015, 10, 11, 23, 59, 59).getTime();

    // 04.02.16 11:11:11 - 09.02.16 23:59:59
    var carnivalWeekStart = new Date(2016, 1, 4, 11, 11, 11).getTime();
    var carnivalWeekEnd = new Date(2016, 1, 9, 23, 59, 59).getTime();

    var now = Date.now();

    return (firstDayStart <= now && now <= firstDayEnd) || (carnivalWeekStart <= now && now <= carnivalWeekEnd);
};