#include <StaticConstants.au3>
#include <EditConstants.au3>

Global Const $SS_ALLCENTER = $SS_CENTER + $SS_CENTERIMAGE

$hWnd = GUICreate("24bt16bcc", 400, 400)
GUISetFont(8.5, 400, 0, "Segoe UI")
GUICtrlCreateLabel("24 bit to 16 bit color converter", 0, 0, 400, 40, $SS_ALLCENTER)
GUICtrlSetFont(-1, 12, 600)
GUICtrlCreateLabel("developed for Arduino SPI displays", 0, 40, 400, 20, $SS_ALLCENTER)
GUICtrlSetFont(-1, 10, 400)

GUICtrlCreateLabel("Input (24 bit hex color value):", 20, 100, 180, 20, $SS_CENTERIMAGE)
$c24Bit = GUICtrlCreateInput("", 200, 100, 180, 20)
GUICtrlCreateLabel("Output (16 bit hex color value):", 20, 140, 180, 20, $SS_CENTERIMAGE)
$c16Bit = GUICtrlCreateInput("", 200, 140, 180, 20, $ES_READONLY)

GUICtrlCreateGroup("Color Preview", 20, 180, 360, 130)
$cInputPreview = GUICtrlCreateLabel("Input", 30, 200, 170, 100, $SS_ALLCENTER)
setPreviewColor($cInputPreview, 0x000000)
$cOutputPreview = GUICtrlCreateLabel("Output", 200, 200, 170, 100, $SS_ALLCENTER)
setPreviewColor($cOutputPreview, 0x000000)

$cConvert = GUICtrlCreateButton("Convert", 100, 330, 200, 50)
Local $aAccelKeys[][] = [["{ENTER}", $cConvert]]
GUISetAccelerators($aAccelKeys)
GUISetState()

While True
	Switch GUIGetMsg()
		Case -3
			Exit
		Case $cConvert
			doConversation()
	EndSwitch
WEnd

Func doConversation()
	;read and clean input color value
	$s24BitColorRaw = GUICtrlRead($c24Bit)
	$aTemp = StringRegExp($s24BitColorRaw, "(?:(?:0x)|(?:#)|)([0-9a-fA-F]{6})", 3)
	If Not IsArray($aTemp) Then
		MsgBox(16, "24bt16bcc", "The input value is invalid. Please change.")
		Return
	EndIf
	$i24Bit = Int("0x" & $aTemp[0])
	;convert input
	$i16Bit = generate16BitFrom24Bit($i24Bit)
	$i16BitPreview = @extended
	setPreviewColor($cInputPreview, $i24Bit)
	setPreviewColor($cOutputPreview, $i16BitPreview)
	;write output back to GUI
	GUICtrlSetData($c16Bit, Hex($i16Bit, 4))
EndFunc   ;==>doConversation

Func setPreviewColor($cControl, $iColor)
	GUICtrlSetBkColor($cControl, $iColor)
	GUICtrlSetColor($cControl, 0xffffff - $iColor)
EndFunc   ;==>setPreviewColor

Func generate16BitFrom24Bit($i24Bit)
	$iRed = BitShift(BitAND($i24Bit, 0xff0000), 16)
	$iGreen = BitShift(BitAND($i24Bit, 0x00ff00), 8)
	$iBlue = BitAND($i24Bit, 0x0000ff)

	$iNewRed = Int(($iRed / 255) * 31)
	$iNewGreen = Int(($iGreen / 255) * 63)
	$iNewBlue = Int(($iBlue / 255) * 31)

	;extra
	$iReRed = Int(($iRed / 255) * 31) * (255/31)
	$iReGreen = Int(($iGreen / 255) * 63) * (255/63)
	$iReBlue = Int(($iBlue / 255) * 31) * (255/31)
	$iRe24Bit = BitShift($iReRed, -16) + BitShift($iReGreen, -8) + $iReBlue
	;end extra

	$i16Bit = BitShift($iNewRed, -11) + BitShift($iNewGreen, -5) + $iNewBlue
	Return SetExtended($iRe24Bit, $i16Bit)
EndFunc   ;==>generate16BitFrom24Bit
