package main

import (
	"os"

	rl "github.com/gen2brain/raylib-go/raylib"
)

const colorCount = 23

func main() {
	const screenWidth, screenHeight int32 = 800, 450

	rl.InitWindow(screenWidth, screenHeight, "raypaint")

	// Colors to choose from
	var colors = [colorCount]rl.Color{
		rl.RayWhite, rl.Yellow, rl.Gold, rl.Orange, rl.Pink, rl.Red, rl.Maroon, rl.Green, rl.Lime, rl.DarkGreen,
		rl.SkyBlue, rl.Blue, rl.DarkBlue, rl.Purple, rl.Violet, rl.DarkPurple, rl.Beige, rl.Brown, rl.DarkBrown,
		rl.LightGray, rl.Gray, rl.DarkGray, rl.Black,
	}

	// Define colorsRecs data (for every rectangle)
	var colorRecs = [colorCount]rl.Rectangle{}

	for i := 0; i < colorCount; i++ {
		colorRecs[i].X = float32(10 + 30*i + 2*i)
		colorRecs[i].Y = 10
		colorRecs[i].Width = 30
		colorRecs[i].Height = 30
	}

	colorSelected := 0
	colorSelectedPrev := colorSelected
	colorMouseHover := 0
	brushSize := 20

	var btnSaveRec = rl.Rectangle{750, 10, 40, 30}
	btnSaveMouseHover := false
	showSaveMessage := false
	saveMessageCounter := 0

	checkSaveHover := func() rl.Color {
		if btnSaveMouseHover {
			return rl.Red
		}
		return rl.Black
	}

	// Create a RenderTexture2D to use as a canvas
	var target rl.RenderTexture2D = rl.LoadRenderTexture(screenWidth, screenHeight)

	// Clear render texture before entering the game loop
	rl.BeginTextureMode(target)
	rl.ClearBackground(colors[0])
	rl.EndTextureMode()

	rl.SetTargetFPS(120)

	// Main game loop
	for !rl.WindowShouldClose() {
		mousePos := rl.GetMousePosition()

		// Move between colors with keys
		if rl.IsKeyPressed(rl.KeyRight) {
			colorSelected++
		} else if rl.IsKeyPressed(rl.KeyLeft) {
			colorSelected--
		}

		if colorSelected >= colorCount {
			colorSelected = colorCount - 1
		} else if colorSelected < 0 {
			colorSelected = 0
		}

		// Choose color with mouse
		for i := 0; i < colorCount; i++ {
			if rl.CheckCollisionPointRec(mousePos, colorRecs[i]) {
				colorMouseHover = i
				break
			} else {
				colorMouseHover = -1
			}
		}

		if colorMouseHover >= 0 && rl.IsMouseButtonPressed(rl.MouseLeftButton) {
			colorSelected = colorMouseHover
			colorSelectedPrev = colorSelected
		}

		// Change brush size
		brushSize += int(rl.GetMouseWheelMove() * 5)
		if brushSize < 2 {
			brushSize = 2
		}

		if brushSize > 50 {
			brushSize = 50
		}

		if rl.IsKeyPressed(rl.KeyC) {
			// Clear render texture to clear color
			rl.BeginTextureMode(target)
			rl.ClearBackground(colors[0])
			rl.EndTextureMode()
		}

		if rl.IsMouseButtonDown(rl.MouseLeftButton) || rl.GetGestureDetected() == rl.GestureDrag {
			// Clear render texture to clear color
			rl.BeginTextureMode(target)

			if mousePos.Y > 50 {
				rl.DrawCircle(int32(mousePos.X), int32(mousePos.Y), float32(brushSize), colors[colorSelected])
			}

			rl.EndTextureMode()
		}

		if rl.IsMouseButtonDown(rl.MouseRightButton) {
			colorSelected = 0

			// Erase circle from render texture
			rl.BeginTextureMode(target)

			if mousePos.Y > 50 {
				rl.DrawCircle(int32(mousePos.X), int32(mousePos.Y), float32(brushSize), colors[0])
			}

			rl.EndTextureMode()
		} else {
			colorSelected = colorSelectedPrev
		}

		if rl.CheckCollisionPointRec(mousePos, btnSaveRec) {
			btnSaveMouseHover = true
		} else {
			btnSaveMouseHover = false
		}

		if btnSaveMouseHover && rl.IsMouseButtonReleased(rl.MouseLeftButton) || rl.IsKeyPressed(rl.KeyS) {
			image := rl.GetTextureData(target.Texture)
			rl.ImageFlipVertical(*&image)
			rl.ExportImage(*image, "export.png")
			rl.UnloadImage(image)
			showSaveMessage = true
		}

		if showSaveMessage {
			// On saving, show a full screen message for 2 seconds
			saveMessageCounter++
			if saveMessageCounter > 240 {
				showSaveMessage = false
				saveMessageCounter = 0
			}
		}

		// Draw
		//----------------------------------------------------------------------------------
		rl.BeginDrawing()

		rl.ClearBackground(rl.RayWhite)

		// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
		rl.DrawTextureRec(target.Texture, rl.Rectangle{0, 0, float32(target.Texture.Width), float32(-target.Texture.Height)}, rl.Vector2{0, 0}, rl.White)

		if mousePos.Y > 50 {
			if rl.IsMouseButtonDown(rl.MouseRightButton) {
				rl.DrawCircleLines(int32(mousePos.X), int32(mousePos.Y), float32(brushSize), rl.Gray)
			} else {
				rl.DrawCircle(rl.GetMouseX(), rl.GetMouseY(), float32(brushSize), colors[colorSelected])
			}
		}

		// Draw top panel
		rl.DrawRectangle(0, 0, int32(rl.GetScreenWidth()), 50, rl.RayWhite)
		rl.DrawLine(0, 50, int32(rl.GetScreenWidth()), 50, rl.LightGray)

		// Draw color selection rectangles
		for i := 0; i < colorCount; i++ {
			rl.DrawRectangleRec(colorRecs[i], colors[i])
		}

		rl.DrawRectangleLines(10, 10, 30, 30, rl.LightGray)

		if colorMouseHover >= 0 {
			rl.DrawRectangleRec(colorRecs[colorMouseHover], rl.Fade(rl.White, 0.0))
		}

		rl.DrawRectangleLinesEx(rl.Rectangle{
			colorRecs[colorSelected].X - 2, colorRecs[colorSelected].Y - 2, colorRecs[colorSelected].Width + 4, colorRecs[colorSelected].Height + 4,
		}, 2, rl.Black)

		// Draw save image button
		rl.DrawRectangleLinesEx(btnSaveRec, 2, checkSaveHover())
		rl.DrawText("SAVE!", 755, 20, 10, checkSaveHover())

		if showSaveMessage {
			rl.DrawRectangle(0, 0, int32(rl.GetScreenWidth()), int32(rl.GetScreenHeight()), rl.Fade(rl.RayWhite, 0.8))
			rl.DrawRectangle(0, 150, int32(rl.GetScreenWidth()), 80, rl.Black)
			rl.DrawText("IMAGE SAVED:  export.png", 150, 180, 20, rl.RayWhite)
		}

		rl.EndDrawing()

	}

	// De-Initialization
	//--------------------------------------------------------------------------------------
	rl.UnloadRenderTexture(target)

	rl.CloseWindow()

	os.Exit(0)

}

