
#include <ButtonConstants.au3>
#include <EditConstants.au3>

Global Const $BG_YELLOW = 0xFFF99A, $BG_GREEN = 0xBCE7C9, $BG_RED = 0xFAC2C4
Global $mMeasures = _MapNew()
$mMeasures.Len = _MapNew()
$mMeasures.Width = _MapNew()
$mMeasures.Room = _MapNew()

Global $hGui = GUICreate('Laminat Calculator', 730, 280)
GUICtrlCreateGroup('  Diele - Länge (mm)  ', 15, 15, 345, 180)
GUICtrlCreateLabel('Volle Länge einer Diele:', 25, 43)
Global $cLenPlank = _CreateInput('', 260, 40, 85, 20)
GUICtrlCreateLabel('Minimaler Versatz (= Mindestlänge):', 25, 73)
Global $cOffset = _CreateInput('400', 260, 70, 85, 20)

GUICtrlCreateLabel('Länge erste Diele, wenn nicht voll ( R1 | R2 ):', 25, 103)
Global $cLenStart = _CreateInput('', 260, 100, 40, 20)
Global $cLenStart2 = _CreateInput('', 305, 100, 40, 20, 'RO')
GUICtrlCreateLabel('Länge der letzten Diele ( R1 | R2 ):', 25, 133)
Global $cLenPart = _CreateInput('', 260, 130, 40, 20, 'RO')
Global $cLenPart2 = _CreateInput('', 305, 130, 40, 20, 'RO')
GUICtrlCreateLabel('Anzahl ganzer Dielen je Reihe:', 25, 163)
Global $cCountPlank = _CreateInput('', 260, 160, 40, 20, 'RO')
Global $cCountPlank2 = _CreateInput('', 305, 160, 40, 20, 'RO')
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUICtrlCreateGroup('  Diele - Breite (mm)  ', 370, 15, 345, 180)
GUICtrlCreateLabel('Volle Breite einer Diele:', 380, 43)
Global $cWidthPlank = _CreateInput('', 615, 40, 80, 20)
GUICtrlCreateLabel('Minimale Breite einer Diele:', 380, 73)
Global $cWidthMin = _CreateInput('50', 615, 70, 80, 20)
GUICtrlCreateLabel('Breite der ersten Reihe, wenn nicht volle Breite:', 380, 103)
Global $cWidthStart = _CreateInput('', 615, 100, 80, 20)
GUICtrlCreateLabel('Breite der letzten Reihe:', 380, 133)
Global $cWidthPart = _CreateInput('', 615, 130, 80, 20, 'RO')
GUICtrlCreateLabel('Anzahl Reihen (inkl. Restbreite):', 380, 163)
Global $cCountLines = _CreateInput('', 615, 160, 80, 20, 'RO')
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUICtrlCreateGroup('  Abmessung Raum (mm)  (Länge = Verlegerichtung längs)  ', 15, 205, 490, 60)
GUICtrlCreateLabel('Länge:', 25, 233)
Global $cLenRoom = _CreateInput('', 80, 230, 85, 20)
GUICtrlCreateLabel('Breite:', 200, 233)
Global $cWidthRoom = _CreateInput('', 260, 230, 85, 20)
GUICtrlCreateLabel('Wandabstand:', 365, 233)
Global $cDistance = _CreateInput('10', 445, 230, 40, 20)
GUICtrlCreateGroup("", -99, -99, 1, 1)

Global $cCalc = GUICtrlCreateButton('Berechnung', 615, 220, 80, 40, $BS_DEFPUSHBUTTON)

GUISetState()

While True
    Switch GUIGetMsg()
        Case -3
            Exit
        Case $cCalc
            _ReadInput()
            _LenCalc()
            _WidthCalc()
    EndSwitch
WEnd


Func _CreateInput($_s, $_x, $_y, $_w, $_h, $_sRO='')
    Local $iStyle = BitOR($ES_RIGHT,$ES_NUMBER), $iBCol = $BG_GREEN
    If $_sRO = 'RO' Then
        $iStyle = BitOR($ES_RIGHT,$ES_NUMBER,$ES_READONLY)
        $iBCol = $BG_YELLOW
    EndIf
    Local $c = GUICtrlCreateInput($_s, $_x, $_y, $_w, $_h, $iStyle)
    GUICtrlSetBkColor(-1, $iBCol)
    Return $c
EndFunc


Func _ReadInput()
    $mMeasures.Len.Plank = GUICtrlRead($cLenPlank)
    $mMeasures.Len.Start = GUICtrlRead($cLenStart)
    $mMeasures.Len.Offset = GUICtrlRead($cOffset)
    $mMeasures.Width.Plank = GUICtrlRead($cWidthPlank)
    $mMeasures.Width.Start = GUICtrlRead($cWidthStart)
    $mMeasures.Width.Min = GUICtrlRead($cWidthMin)
    $mMeasures.Room.Len = GUICtrlRead($cLenRoom)
    $mMeasures.Room.Width = GUICtrlRead($cWidthRoom)
    $mMeasures.Room.Distance = GUICtrlRead($cDistance)
EndFunc


Func _CheckInput($_iType=0)
    Local $iErr = 0
    If $_iType = 0 Then
        $iErr += ($mMeasures.Len.Plank = 0 ? 1 : 0)
        $iErr += ($mMeasures.Len.Offset = 0 ? 1 : 0)
        $iErr += ($mMeasures.Room.Len = 0 ? 1 : 0)
        $mMeasures.Len.Start = $mMeasures.Len.Start = 0 ? $mMeasures.Len.Plank : $mMeasures.Len.Start
    Else
        $iErr += ($mMeasures.Width.Plank = 0 ? 1 : 0)
        $iErr += ($mMeasures.Width.Min = 0 ? 1 : 0)
        $iErr += ($mMeasures.Room.Width = 0 ? 1 : 0)
    EndIf
    $iErr += ($mMeasures.Room.Distance = 0 ? 1 : 0)
    Return SetError($iErr)
EndFunc


Func _LenCalc()
    _CheckInput()
    If @error Then Return
    ; Reihe 1
    Local $iFull = $mMeasures.Room.Len - (2*$mMeasures.Room.Distance)
    $iFull -= $mMeasures.Len.Start
    Do
        $iFull -= $mMeasures.Len.Plank
    Until $iFull < $mMeasures.Len.Plank
    $mMeasures.Len.Part = $iFull = 0 ? $mMeasures.Len.Plank : $iFull
    GUICtrlSetData($cLenPart, $mMeasures.Len.Part)
    GUICtrlSetBkColor($cLenPart, $BG_YELLOW)
    If Number($mMeasures.Len.Part) < Number($mMeasures.Len.Offset) Then GUICtrlSetBkColor($cLenPart, $BG_RED)
    GUICtrlSetData($cLenStart, $mMeasures.Len.Start)
    GUICtrlSetData($cCountPlank, _CountPlanks($mMeasures.Len.Start, $mMeasures.Len.Part))
    ; Reihe 2
    Local $iStart1 = $mMeasures.Len.Start
    Local $iStart2
    Select
        Case $mMeasures.Len.Part = $mMeasures.Len.Plank
            Select
                Case $iStart1 = $mMeasures.Len.Plank
                    $iStart2 = $mMeasures.Len.Plank / 2
                Case $iStart1 - $mMeasures.Len.Offset >= $mMeasures.Len.Offset
                    $iStart2 = $iStart1 - $mMeasures.Len.Offset
                Case $iStart1 + $mMeasures.Len.Offset <= $mMeasures.Len.Plank
                    $iStart2 = $iStart1 + $mMeasures.Len.Offset
            EndSelect
        Case $iStart1 - $mMeasures.Len.Part >= $mMeasures.Len.Offset
            $iStart2 = $iStart1 - $mMeasures.Len.Part
        Case $iStart1 + $mMeasures.Len.Part <= $mMeasures.Len.Plank
            $iStart2 = $iStart1 + $mMeasures.Len.Part
        Case Else
            $iStart2 = $iStart1 + $mMeasures.Len.Offset
    EndSelect
    GUICtrlSetData($cLenStart2, $iStart2)
    $iFull = $mMeasures.Room.Len - (2*$mMeasures.Room.Distance)
    $iFull -= GUICtrlRead($cLenStart2)
    Do
        $iFull -= $mMeasures.Len.Plank
    Until $iFull < $mMeasures.Len.Plank
    ; Anfangslänge evtl. anpassen um volle Länge am Ende zu haben
    Local $iTmp = $iFull + GUICtrlRead($cLenStart2) - $mMeasures.Len.Plank
    If $iTmp >= $mMeasures.Len.Offset Then
        GUICtrlSetData($cLenStart2, $iTmp)
        $iFull = $mMeasures.Len.Plank
    EndIf
    If $iFull = 0 Then $iFull = $mMeasures.Len.Plank
    GUICtrlSetData($cCountPlank2, _CountPlanks($iStart2, $iFull))
    GUICtrlSetData($cLenPart2, $iFull)
    GUICtrlSetBkColor($cLenPart2, $BG_YELLOW)
    If Number($iFull) < Number($mMeasures.Len.Offset) Then GUICtrlSetBkColor($cLenPart2, $BG_RED)
EndFunc


Func _CountPlanks($_start, $_end)
    Local $count = 0
    $_start = $_start = 0 ? $mMeasures.Len.Plank : $_start
    If $_start = $mMeasures.Len.Plank Then $count += 1
    If $_end = $mMeasures.Len.Plank Then $count += 1
    Local $l = $mMeasures.Room.Len - (2*$mMeasures.Room.Distance) - $_start - $_end
    $count += $l / $mMeasures.Len.Plank
    Return $count
EndFunc


Func _WidthCalc()
    _CheckInput(1)
    If @error Then Return
    Local $iFull = $mMeasures.Room.Width - (2*$mMeasures.Room.Distance)
    Local $nCount = Ceiling($iFull / $mMeasures.Width.Plank)
    $iFull -= $mMeasures.Width.Start
    Do
        $iFull -= $mMeasures.Width.Plank
    Until $iFull < $mMeasures.Width.Plank
    $mMeasures.Width.Part = $iFull = 0 ? $mMeasures.Width.Plank : $iFull
    GUICtrlSetData($cWidthPart, $mMeasures.Width.Part)
    GUICtrlSetData($cCountLines, $nCount)
    GUICtrlSetBkColor($cWidthPart, $BG_YELLOW)
    If Number($mMeasures.Width.Part) < Number($mMeasures.Width.Min) Then GUICtrlSetBkColor($cWidthPart, $BG_RED)
EndFunc


Func _MapNew()
    Local $m[]
    Return $m
EndFunc
