/****************************************************************************
**
** Copyright (C) 2025 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the FOO module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

/******************** Desktop **************************************/
var qt6Init = "qt.qt6"
var qt6Version = "6100"
var qt6DisplayVersion = "6.10"

var desktop6 = qt6Init + "." + qt6Version;
var mobileiOS = desktop6 + ".ios"
var mobileAndroid = desktop6 + ".android"
var desktop6macOS = desktop6 + ".clang_64"
var desktop6Windows = "";
var desktop6Linux = "";
if (systemInfo.currentCpuArchitecture == "arm64") {
    desktop6Windows = desktop6 + ".win64_msvc2022_arm64";
    desktop6Linux = desktop6 + ".linux_gcc_arm64";
}
else {
    desktop6Windows = desktop6 + ".win64_mingw";
    desktop6Linux = desktop6 + ".linux_gcc_64";
}

//dependencies for Qt6 examples
var qt6AddonDependencyQuick3D = desktop6 + ".addons.qtquick3d";
var qt6AddonDependencyShaderTools = desktop6 + ".addons.qtshadertools";
var qt6AddonDependencyMultimedia = desktop6 + ".addons.qtmultimedia";
var qt6AddonDependencyCharts = desktop6 + ".addons.qtcharts";

// tool dependencies for Qt6 desktop default selection
var qt6QtCreatorDependency = "qt.tools.qtcreator_gui"
var qt6CMakeDependency = "qt.tools.cmake"
var qt6NinjaDependency = "qt.tools.ninja"

/******************** Design Studio *****************************************/
var toolsDesignStudio = "qt.tools.qtdesignstudio"

/******************** GENERAL ***********************************************/
var targetPlaceholderText = QT_TR_NOOP("Select target device")
var qt6DesktopDescription = QT_TR_NOOP("Create applications from one codebase to multiple desktop platforms.");
var qt6MobileDescription = QT_TR_NOOP("Create applications from one codebase to all mobile platforms.");
var designStudioDescription = QT_TR_NOOP("Turn design visions into functional products & working prototypes.");


var productTypeDev = QT_TR_NOOP("Developer tools");
var productTypeDesign = QT_TR_NOOP("Visual creation tools");
var customInstall = QT_TR_NOOP("Custom Installation");
var customInstallDescription = QT_TR_NOOP("User selectable packages. Host platform and developer license restrictions apply.");

var desktopDevelopment = QT_TR_NOOP("Qt %1 for desktop development");
var designTools = QT_TR_NOOP("Qt Design Studio");
var mobileDevelopment = QT_TR_NOOP("Qt %1 for mobile development");


var mainTargetsJSON = '{ "items" : [' +
    '{ "id": "' + desktop6Windows + '", "name": "' + qsTranslate("installscript", desktopDevelopment).arg(qt6DisplayVersion) + '", "description": "' + qt6DesktopDescription + '" },' +
    '{ "id": "' + desktop6macOS + '", "name": "' + qsTranslate("installscript", desktopDevelopment).arg(qt6DisplayVersion) + '", "description": "' + qt6DesktopDescription + '" },' +
    '{ "id": "' + desktop6Linux + '", "name": "' + qsTranslate("installscript", desktopDevelopment).arg(qt6DisplayVersion) + '", "description": "' + qt6DesktopDescription + '" },' +
    '{ "id": "' + toolsDesignStudio + '", "name": "' + designTools + '" , "description": "' + designStudioDescription + '" },' +
    '{ "id": "' + mobileiOS + '", "name": "' + qsTranslate("installscript", mobileDevelopment).arg(qt6DisplayVersion) + '", "description": "' + qt6MobileDescription + '" },' +
    '{ "id": "' + mobileAndroid + '", "name": "' + qsTranslate("installscript", mobileDevelopment).arg(qt6DisplayVersion) + '", "description": "' + qt6MobileDescription + '" } ]}';

/******************** INTERNAL *************************************/
var mainTargets = JSON.parse(mainTargetsJSON);

function getItemValueForTarget(id, prop){
    for (var i =0; i < mainTargets.items.length; i++){
        if (mainTargets.items[i].id === id) {
            if (mainTargets.items[i].hasOwnProperty(prop) === true)
                return mainTargets.items[i][prop];
            else
                return "";
        }
    }
    return "";
}

var selectionWidget;
var componentsToInstall = [];

var qt6DesktopAndAddonDependencies = [];
var qt6MobileComponents = [];
var qtDesignStudioComponent;
var ifwVersion;

var selectedFrames = [];
var oldPageId = 0;

function Component()
{
    // This repository contains feature that is available only from IFW 4.1.1 onwards (QTIFW-2225)
    // Stop supporting default install view for versions earlier than IFW 4.7.0
    ifwVersion = installer.value("FrameworkVersion");
    if (!installer.isInstaller() || installer.versionMatches(ifwVersion, "<4.7.0"))
        return;

    if (installer.isCommandLineDefaultInstall()) {
        var installComponent;
        if (installer.value("os") == "win")
            installComponent = Component.prototype.getComponent(desktop6Windows);
        else if (installer.value("os") == "mac")
            installComponent = Component.prototype.getComponent(desktop6macOS);
        else
            installComponent = Component.prototype.getComponent(desktop6Linux);

        if (installComponent != "")
            installer.componentByName(installComponent).setValue("Default", "true");
    } else if (installer.addWizardPageItem(component, "InstallTypeWidgetFrame", QInstaller.TargetDirectory, 0))
            component.loaded.connect(this, Component.prototype.loaded);
}

Component.prototype.getAvailableTargets = function(qtVersionId, targets)
{
    var availableTargets = [];
    if (!targets)
        return availableTargets;
    var components = installer.components(qtVersionId);
    for (i = 0; i < targets.items.length; i++) {
        for (j = 0; j < components.length; j++) {
            var componentName = components[j].name;
            var componentId = componentName.slice(qtVersionId.length + 1);
            if (componentId == targets.items[i].id) {
                targets.items[i].name = components[j].displayName;
                var availableTargetItem = {};
                availableTargetItem.name = components[j].displayName;
                availableTargetItem.id = componentId;
                availableTargets.push(availableTargetItem);
                break;
            }
        }
    }
    return availableTargets;
}

Component.prototype.deselectAllComponents = function()
{
    for (i = 0; i < componentsToInstall.length; i++) {
        var component = installer.componentByName(componentsToInstall[i]);
        if (component) {
            installer.deselectComponent(componentsToInstall[i]);
            installer.componentByName(componentsToInstall[i]).setValue("Default", "false");
        }
    }
}

Component.prototype.addOrRemoveDependencies = function(componentsToInstall, dependencies, add)
{
    if (add) {
        componentsToInstall = componentsToInstall.concat(dependencies);
    } else {
        dependencies.forEach(name => {
            let index = componentsToInstall.indexOf(name);
            if (index !== -1) {
                componentsToInstall.splice(index, 1);
            }
        });
    }
    return componentsToInstall;
}

Component.prototype.componentSelected = function(id, isSelected)
{
    if (id.trim().length <=0)
        return;
    Component.prototype.deselectAllComponents();
    if (isSelected && !selectedFrames.includes(id)) {
        selectedFrames.push(id)
    } else if (!isSelected) {
        var index = selectedFrames.indexOf(id);
        if (index != -1)
            selectedFrames.splice(index, 1);
    }
    installer.setValue("QtInstallerDefaultSelectionFrames", selectedFrames)

    if (id == "custom") {
        // Below version 4.9.0, if custom is clicked then all other boxes cannot be selected,
        // and we show the component tree.
        // After 4.9.0, both custom and other boxes can be selected, then we show the component tree
        // with the components preselected from the boxes
        if (installer.versionMatches(ifwVersion, "<4.9.0")) {
            componentsToInstall = [];
            var designStudioComponent = installer.componentByName(toolsDesignStudio);
            if (designStudioComponent && designStudioComponent.value("Default") == "true")
                installer.selectComponent(toolsDesignStudio);
            installer.clearComponentsToInstallCalculated();
            installer.calculateComponentsToInstall();
        } else {
            installer.setDefaultPageVisible(QInstaller.ComponentSelection, isSelected);
        }
    } else if (id == "desktop") {
        componentsToInstall = Component.prototype.addOrRemoveDependencies(componentsToInstall, qt6DesktopAndAddonDependencies, isSelected);
    } else if (id == "mobile") {
        componentsToInstall = Component.prototype.addOrRemoveDependencies(componentsToInstall, qt6MobileComponents, isSelected);
    } else {
        if (isSelected) {
            componentsToInstall.push(id);
        } else {
            var index = componentsToInstall.indexOf(id);
            if (index != -1)
                componentsToInstall.splice(index, 1);
        }
    }
    if (installer.versionMatches(ifwVersion, "<4.9.0")) {
        if (componentsToInstall.length == 0) {
            installer.setDefaultPageVisible(QInstaller.ComponentSelection, true);
        } else {
            installer.setDefaultPageVisible(QInstaller.ComponentSelection, false);
        }
    }

    Component.prototype.selectComponentsForInstallation();
}

Component.prototype.getComponent = function(qtVersionId, targets)
{
    var selectedComponent = "";
    if (targets == undefined) {
        if (installer.componentByName(qtVersionId) != null)
            selectedComponent = qtVersionId;
    } else {
        var components = installer.components(qtVersionId);
loop1:
        for (i = 0; i < targets.items.length; i++) {
loop2:
            for (j = 0; j < components.length; j++) {
                var componentName = components[j].name;
                var componentId = componentName.slice(qtVersionId.length + 1);
                if (componentId == targets.items[i].id) {
                    selectedComponent = componentName;
                    break loop1;
                }
            }
        }
    }
    return selectedComponent;
}

Component.prototype.initFrameItem = function(objectName, productTypeStr, qtVersionId, targets)
{
    var selectedComponent = Component.prototype.getComponent(qtVersionId, targets);
    if (selectedComponent != "") {
        var titleText = qsTranslate("installscript", getItemValueForTarget(qtVersionId, "name"));
        var description = qsTranslate("installscript", getItemValueForTarget(qtVersionId, "description"));
        var availableTargets = Component.prototype.getAvailableTargets(qtVersionId, targets);
        if (installer.versionMatches(ifwVersion, "<4.9.0"))
            selectionWidget.addItem(objectName, qtVersionId, productTypeStr, titleText, description, availableTargets);
        else
            selectionWidget.addItem(objectName, qtVersionId, productTypeStr, titleText, description, availableTargets, targetPlaceholderText);
    }
}

Component.prototype.initMobileItemsAndFrame = function(objectName, productTypeStr, id, dependencies)
{
    var selectedComponents = [];
    var components = [];
    for (i = 0; i < dependencies.length; i++)
        components = components.concat(installer.components("^" + dependencies[i] + "$"));

    for (j = 0; j < components.length; j++) {
        var componentName = components[j].name;
        selectedComponents.push(componentName);
    }

    if (selectedComponents.length > 0) {
        var titleText = qsTranslate("installscript", getItemValueForTarget(dependencies[0], "name"));
        var description = qsTranslate("installscript", getItemValueForTarget(dependencies[0], "description"));
        selectionWidget.addItem(objectName, id, productTypeStr, titleText, description);
    }
    return selectedComponents;
}

Component.prototype.loaded = function()
{
    selectionWidget = component.userInterface("InstallTypeWidgetFrame").defaultInstall;
    var desktopDependencies = [qt6AddonDependencyQuick3D,
                               qt6AddonDependencyMultimedia,
                               qt6AddonDependencyShaderTools,
                               qt6AddonDependencyCharts,
                               qt6QtCreatorDependency,
                               qt6CMakeDependency,
                               qt6NinjaDependency];
    if (selectionWidget != null) {
        selectionWidget.selectedChanged.connect(Component.prototype.componentSelected);
        // Custom installation
        selectionWidget.addItem("custom", "custom", "", qsTr(customInstall), qsTr(customInstallDescription));
        if (installer.value("os") == "win")
            desktopDependencies.unshift(desktop6Windows);
        else if (installer.value("os") == "mac")
            desktopDependencies.unshift(desktop6macOS);
        else
            desktopDependencies.unshift(desktop6Linux);
        qt6DesktopAndAddonDependencies = desktopDependencies.slice();

        Component.prototype.initMobileItemsAndFrame("desktop", qsTr(productTypeDev), "desktop", qt6DesktopAndAddonDependencies);
        var mobileTargets = [mobileAndroid, mobileiOS]
        qt6MobileComponents = Component.prototype.initMobileItemsAndFrame("mobile", qsTr(productTypeDev), "mobile", mobileTargets);
        Component.prototype.initFrameItem("designstudio", qsTr(productTypeDesign), toolsDesignStudio);
    } else {
        console.log("Selection widget not found");
    }
    if (installer.versionMatches(ifwVersion, ">=4.9.0")) {
        selectionWidget.addSpaceInformationWidget(installer);
        installer.finishedCalculateComponentsToInstall.connect(Component.prototype.updateSpaceRequiredText);
        installer.finishAllComponentsReset.connect(Component.prototype.selectInitialFrame);
        installer.currentPageChanged.connect(Component.prototype.currentPageChanged);
    }
}

Component.prototype.currentPageChanged = function(newId)
{
    if (oldPageId == QInstaller.ComponentSelection && newId == QInstaller.TargetDirectory) {
        // We have returned from component selection page, frames are still selected but user
        // might have deselected the components in previous page. Reselect the components.
        Component.prototype.selectComponentsForInstallation();
    }
    oldPageId = newId;
}

Component.prototype.selectInitialFrame = function()
{
    // We have once selected the frames, reselect after category fetch
    if (installer.containsValue("QtInstallerDefaultPageInitialized")) {
        if (!installer.containsValue("QtInstallerDefaultSelectionFrames"))
            return;

        var framesSelected = installer.value("QtInstallerDefaultSelectionFrames").split(",");
        selectionWidget.selectItems(framesSelected);
        return;
    }

    // Try selecting desktop item first. If not found, then select custom installation.
    // If user has typed --nd when running installer, custom is selected.
    var selectCustomInstallation = false;
    if (installer.noDefaultInstallation() || selectionWidget.selectItem("desktop") === false)
        selectCustomInstallation = true;
    if (selectCustomInstallation)
        selectionWidget.selectItem("custom");
    else
        installer.setDefaultPageVisible(QInstaller.ComponentSelection, false);
    // Set helper value so that installer can reselect the frames after category fetch
    installer.setValue("QtInstallerDefaultPageInitialized", true)
}

Component.prototype.updateSpaceRequiredText = function()
{
    if (selectionWidget != null)
        selectionWidget.updateSpaceRequiredText();
}

Component.prototype.selectComponentsForInstallation = function()
{
    for (j = 0; j < componentsToInstall.length; j++) {
        var component = installer.componentByName(componentsToInstall[j]);
        if (component) {
            installer.selectComponent(componentsToInstall[j]);
            installer.componentByName(componentsToInstall[j]).setValue("Default", "true");
        } else {
            console.log("Component not found " + componentsToInstall[j]);
        }
    }

    if ((componentsToInstall.length == 1) && (componentsToInstall[0] == toolsDesignStudio))
        installer.setValue("DesignStudioInstallOnly", true);
    else
        installer.setValue("DesignStudioInstallOnly", false);

    installer.clearComponentsToInstallCalculated();
    installer.calculateComponentsToInstall()
}
