package gui

import "core:fmt"
import "core:os"
import "../core"
import "../shared"

collect_script_panels :: proc(script: core.Comic_Script) -> []core.Panel {
	out: [dynamic]core.Panel
	for p in script.pages {
		for pan in p.panels {
			append(&out, pan)
		}
	}
	return out[:]
}

count_script_panels :: proc(script: core.Comic_Script) -> int {
	count := 0
	for p in script.pages {
		count += len(p.panels)
	}
	return count
}

local_panel_id_by_index :: proc(i: int) -> string {
	switch i {
	case 0: return "panel_local_001"
	case 1: return "panel_local_002"
	case 2: return "panel_local_003"
	case 3: return "panel_local_004"
	case 4: return "panel_local_005"
	case 5: return "panel_local_006"
	}
	return "panel_local_overflow"
}

build_local_script :: proc(story_idea: string, pages: int) -> core.Comic_Script {
	out_pages: [dynamic]core.Page
	for i in 0..<pages {
		chars_present := make([]string, 1)
		chars_present[0] = "char_001"
		dialogue := make([]core.Dialogue, 1)
		dialogue[0] = core.Dialogue{speaker_id = "char_001", text = "Let's do this.", bubble_type = .Normal, emotion = .Neutral}

		panel := core.Panel{
			panel_id = local_panel_id_by_index(i),
			panel_number = 1,
			shot_type = .Medium,
			description = story_idea,
			characters_present = chars_present,
			dialogue = dialogue,
			caption = "",
			sound_effects = nil,
			transition_from_previous = .None,
		}
		panels := make([]core.Panel, 1)
		panels[0] = panel
		append(&out_pages, core.Page{page_number = i + 1, layout_type = .Grid, panels = panels})
	}

	chars := make([]core.Character, 1)
	chars[0] = core.Character{id = "char_001", name = "Protagonist", role = .Protagonist, description = "Main character"}
	return core.Comic_Script{title = "Local Script", synopsis = story_idea, characters = chars, pages = out_pages[:]}
}

build_local_panel_images :: proc(panels: []core.Panel) -> (map[string]core.Panel_Image, shared.App_Error) {
	tmp_dir, terr := os.make_directory_temp("", "comic-gui-local-panels-*", context.temp_allocator)
	if terr != nil {
		return nil, shared.new_error(.Generation, "failed to create local panel temp dir", true)
	}

	images := make(map[string]core.Panel_Image)
	for p, idx in panels {
		name := fmt.aprintf("panel_%03d_%s.png", idx+1, p.panel_id)
		out_path := fmt.aprintf("%s/%s", tmp_dir, name)
		delete(name)

		// Create a real PNG image using python3
		gen_w := 1024
		gen_h := 1024
		py_script := fmt.aprintf(
			"import struct,zlib,sys;w,h=%d,%d;rows=[]\nfor _ in range(h): rows.append(b'\\x00'+b'\\xff\\xff\\xff'*w)\nraw=b''.join(rows);comp=zlib.compress(raw)\ndef crc(d): return struct.pack('>I',zlib.crc32(d)&0xffffffff)\nf=open(sys.argv[1],'wb')\nf.write(b'\\x89PNG\\r\\n\\x1a\\n')\nihdr_data=struct.pack('>IIBBBBB',w,h,8,2,0,0,0)\nf.write(struct.pack('>I',13)+b'IHDR'+ihdr_data+crc(b'IHDR'+ihdr_data))\nf.write(struct.pack('>I',len(comp))+b'IDAT'+comp+crc(b'IDAT'+comp))\nf.write(struct.pack('>I',0)+b'IEND'+crc(b'IEND'))\nf.close()",
			gen_w, gen_h,
		)
		defer delete(py_script)

		py_cmd := [4]string{"python3", "-c", py_script, out_path}
		desc := os.Process_Desc{command = py_cmd[:]}
		state, _, stderr, cerr := os.process_exec(desc, context.temp_allocator)
		if cerr != nil || !state.exited || state.exit_code != 0 {
			delete(out_path)
			msg := fmt.aprintf("failed to create panel image: %s", string(stderr))
			defer delete(msg)
			return nil, shared.new_error(.Generation, msg, true)
		}

		url := fmt.aprintf("file://%s", out_path)
		prompt := fmt.aprintf("local panel %d", idx+1)
		images[p.panel_id] = core.Panel_Image{url = url, width = gen_w, height = gen_h, seed = i64(idx + 1), prompt = prompt}
		delete(out_path)
	}
	return images, shared.ok()
}

append_char :: proc(dst: ^string, ch: rune) {
	dst^ = fmt.aprintf("%s%c", dst^, ch)
}

pop_char :: proc(dst: ^string) {
	if len(dst^) == 0 {
		return
	}
	dst^ = dst^[:len(dst^)-1]
}
