from __future__ import annotations

from typing import Tuple

from ..common.base_parameter_control import BaseParameterControl
from ..common.master_file_widget import MasterFileWidget
from ..common.tolerance_selector import ToleranceSelector
from ..common.tuple_input_widget import TupleInputWidget
from ..common.utils import NoWheelDoubleSpinBox
from ..common.utils import NoWheelSpinBox
from ..indexer.constants import INDEXER_TOOLTIPS


class IndexerSettings(BaseParameterControl):
    def __init__(self, parent=None):
        super().__init__(title="Indexer Settings", parent=parent)
        layout = self.settingsLayout
        self._rings = TupleInputWidget(placeHolderText="e.g. 0, 1", Type=int)
        self._rings.setToolTip(INDEXER_TOOLTIPS["genrings"])
        self._scoringRings = TupleInputWidget(placeHolderText="e.g. 0, 1, 2", Type=int)
        self._scoringRings.setToolTip(INDEXER_TOOLTIPS["scorerings"])

        self._maxGrains = NoWheelSpinBox()
        self._maxGrains.setToolTip(INDEXER_TOOLTIPS["maxGrains"])
        self._maxGrains.setValue(1000)
        self._dstol = NoWheelDoubleSpinBox()
        self._dstol.setMinimum(0)
        self._dstol.setValue(0.004)
        self._dstol.setToolTip(INDEXER_TOOLTIPS["dstol"])

        self._HKLIndicesTol = ToleranceSelector()

        self._wavelength = NoWheelDoubleSpinBox()
        self._wavelength.setMinimum(0)
        self._wavelength.setToolTip(INDEXER_TOOLTIPS["wavelength"])
        self._latticeFile = MasterFileWidget("Select Lattice File")
        self._latticeFile.setNameFilters(["Par Files (*.par)", "CIF Files (*.cif)"])

        layout.addRow("Rings for grain generation", self._rings)
        layout.addRow("Rings for grain scoring", self._scoringRings)
        layout.addRow("Maximum number of grains", self._maxGrains)
        layout.addRow("Reciprocal Distance Tolerance", self._dstol)
        layout.addRow("HKL Tolerance", self._HKLIndicesTol)
        layout.addRow("Wavelength", self._wavelength)
        layout.addRow("Lattice File", self._latticeFile)

    def getRings(self) -> tuple:
        return self._rings.getValue()

    def getScoringRings(self) -> tuple:
        return self._scoringRings.getValue()

    def getMaxGrains(self) -> int | None:
        return self._maxGrains.value()

    def getReciprocalDist(self) -> float:
        return self._dstol.value()

    def getHKLSEQTOL(self) -> tuple:
        return self._HKLIndicesTol.getValue()

    def getLatticeFile(self) -> str:
        return self._latticeFile.getText()

    def getWavelength(
        self,
    ) -> float:
        return self._wavelength.value()

    def setRings(self, values: Tuple[int, ...]):
        self._rings.setValue(values)

    def setScoringRings(self, values: Tuple[int, ...]):
        self._scoringRings.setValue(values)

    def setMaxGrains(self, value: int | None):
        self._maxGrains.setValue(value)

    def setReciprocalDist(self, value: float):
        self._dstol.setValue(value)

    def setHKLSEQTOL(self, hklSeq: Tuple[float, ...]):
        self._HKLIndicesTol.setValue(hklSeq)

    def setLatticeFile(self, latticeFile: str):
        self._latticeFile.setText(latticeFile)

    def setWavelength(self, wavelength: float):
        self._wavelength.setValue(wavelength)

    def validate(self):
        self._rings.getValue()
        self._scoringRings.getValue()
