shithub: wildlife

ref: 50c527fe9f81010d304f49ce51dfc39a16cdec6c
dir: wildlife/main.go

View raw version
package main

import (
	"9fans.net/go/draw"
	"bytes"
	"fmt"
	"image"
	imagedraw "image/draw"
	"flag"
	"github.com/mjl-/duit"
	"github.com/psilva261/szdd"
	xdraw "golang.org/x/image/draw"
	"log"
	"math"
	"os"

	_ "golang.org/x/image/bmp"
	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
)

var (
	dui *duit.DUI
	scale int

	history []*Item
	lastM draw.Mouse
)

type Category int

const (
	About Category = iota
	Animal
)

func (c Category) path() string {
	switch c {
	case About:
		return "about"
	case Animal:
		return "animal"
	}
	log.Fatalf("%v unknown", c)
	return ""
}

type Folder struct {
	Category

	Pre string
	Suf string
	Name string
	Items map[string]*Item
}

func getFolder(root, pre string) (ff *Folder) {
	for _, f := range folders {
		if f.Pre == pre {
			ff = f
		}
	}
	return
}

func (f Folder) Main() *Item {
	fnSuf := f.Suf
	if _, ok := f.Items[f.Suf]; !ok {
		fnSuf = "0001"
	}
	return f.getItem(fnSuf)
}

func (f *Folder) Decode(k string) (fName, itName string) {
	if _, ok := f.Items[k]; ok {
		return f.Pre, k
	}
	var ff *Folder
	fName = k
	for _, fff := range folders {
		if fff.Pre == k {
			ff = fff
		}
	}
	if ff == nil {
		return f.Pre, k
	}
	itName = ff.Suf
	if _, ok := ff.Items[itName]; !ok {
		itName = "0001"
	}
	return
}

func (f Folder) getItem(k string) *Item {
	for key, it := range f.Items {
		if key == k {
			if it.Image == nil {
				fn := fmt.Sprintf("./data/%v/%v%v/%v%v.dib", f.Category.path(), f.Pre, f.Suf, f.Pre, k)
				it.Image = &duit.Image{
					Image: readImagePath(fn),
				}
			}
			return it
		}
	}
	return nil
}

type Item struct {
	*duit.Image

	f *Folder
	name string
	Targets map[string]Target
}

func (it *Item) Mouse(dui *duit.DUI, self *duit.Kid, m draw.Mouse, origM draw.Mouse, orig image.Point) (r duit.Result) {
	defer func() {
		lastM = m
	}()
	if m.Buttons&1 == 1 && lastM.Buttons&1 == 0 {
		//log.Printf("m= %v,%v", m.Point.X*2/scale, m.Point.Y*2/scale)
		for k, t := range it.Targets {
			if t.has(m.Point) {
				history = append(history, it)
				fName, itName := it.f.Decode(k)
				_=fName
				tf := getFolder(it.f.Pre, k)
				if tf == nil {
					tf = it.f
				}
				it := tf.getItem(itName)
				dui.Top.UI = it
				dui.MarkLayout(dui.Top.UI)
				dui.MarkDraw(dui.Top.UI)
				dui.Render()
			}
		}
		return duit.Result{
			Consumed: true,
		}
	} else if m.Buttons&4 == 4 {
		var it *Item
		if l := len(history); l > 0 {
			it, history = history[l-1], history[:l-1]
		} else {
			tf := getFolder("", "cont")
			it = tf.Main()
		}
		dui.Top.UI = it
		dui.MarkLayout(dui.Top.UI)
		dui.MarkDraw(dui.Top.UI)
		dui.Render()
	}
	return it.Image.Mouse(dui, self, m, origM, orig)
}

type Target interface {
	has(draw.Point) bool
}

type Circle struct {
	x int
	y int
	r int
}

func C(x, y, r int) Circle {
	return Circle{x: x, y: y, r: r}
}

func (c Circle) has(p draw.Point) bool {
	x := p.X * 2 / scale
	y := p.Y * 2 / scale
	return math.Abs(float64(x)-float64(c.x)) < float64(c.r) && math.Abs(float64(y)-float64(c.y)) < float64(c.r)
}

type Rectangle struct {
	x int
	y int
	x2 int
	y2 int
}

func R(x, y, x2, y2 int) Rectangle {
	return Rectangle{x: x, y: y, x2: x2, y2: y2}
}

func (r Rectangle) has(p draw.Point) bool {
	x := p.X * 2 / scale
	y := p.Y * 2 / scale
	return r.x <= x && x <= r.x2 && r.y <= y && y <= r.y2
}

var folders = []*Folder{
	/* about */
	&Folder{
		Pre: "afri",
		Suf: "00aa",
		Name: "Africa",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Waterhole",
			},
			"00fb": &Item{
				name: "Art",
			},
		},
	},
	&Folder{
		Pre: "atls",
		Suf: "00nv",
		Name: "Atlas",
		Items: map[string]*Item{
			"00nv": &Item{
				name: "Continents",
				Targets: map[string]Target{
					"01pu": C(659, 461, 100),
					"02pu": C(931, 275, 200),
					"03pu": C(1117, 603, 50),
					"04pu": C(600, 262, 50),
					"05pu": C(222, 270, 140),
					"06pu": C(350, 552, 120),
				},
			},
			"01p1": &Item{
				name: "African reptiles",
			},
			"01p2": &Item{
				name: "African herbivores",
			},
			"01pu": &Item{
				name: "Africa",
				Targets: map[string]Target{
					"leop": C(114,610,80),
					"babn": C(348,568,55),
					"cock": C(474,716,40),
					"01p2": C(200,292,100),
					"01p1": C(680,539,100),
					"lion": C(468,360,60),
					"rats": C(391,74,60),
					"mosq": C(218,147,40),
					"aant": C(575,124,50),
					"chee": C(814,256,70),
					"vult": C(849,72, 90),
					"hyen": C(906,666,60),
					"cdog": C(1104,642,80),
					"fsal": C(1074,428,100),
					"kbee": C(1130,252,60),
					"afri": C(1150,68,50),
				},
			},
			"02pu": &Item{
				name: "Asia",
			},
			"03pu": &Item{
				name: "Australia",
			},
			"04pu": &Item{
				name: "Europe",
				Targets: map[string]Target{
					"addr": C(852,367,60),
					"cent": C(714,699, 100),
					"cock": C(69,256, 100),
					"crab": C(1013,175, 65),
					"fsal": C(670,497,80),
					"gsqu": C(411,95,75),
					"mosq": C(728,59,50),
					"rats": C(288,325, 100),
					"scor": C(160,593, 90),
					"vult": C(418,610, 70),
					"wlvr": C(609,193, 70),
					"wolf": C(1101, 546, 100),
				},
			},
			"05pu": &Item{
				name: "North America",
			},
			"06pu": &Item{
				name: "South America",
			},
		},
	},
	&Folder{
		Pre: "aust",
		Suf: "00aa",
		Name: "Australia",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Oddities",
			},
		},
	},
	&Folder{
		Pre: "beet",
		Suf: "00aa",
		Name: "Beetles",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Beetles",
			},
		},
	},
	&Folder{
		Pre: "frst",
		Suf: "00aa",
		Name: "Forest",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Forest Environments",
			},
		},
	},
	&Folder{
		Pre: "cont",
		Suf: "00nv",
		Name: "Contents",
		Items: map[string]*Item{
			"00nv": &Item{
				name: "Contents",
				Targets: map[string]Target{
					"atls": C(242, 190, 150),
					"habt": C(256, 588, 200),
					"indx": C(920, 614, 200),
					"weap": C(997, 200, 200),
					"wwfd": C(604, 384, 200),
				},
			},
		},
	},
	&Folder{
		Pre: "guid",
		Suf: "00nv",
		Name: "Guides",
		Items: map[string]*Item{
			"00nv": &Item{
				name: "Guides",
			},
		},
	},
	&Folder{
		Pre: "habt",
		Suf: "00nv",
		Name: "Habitats",
		Items: map[string]*Item{
			"00nv": &Item{
				name: "Habitats",
			},
		},
	},
	&Folder{
		Pre: "help",
		Suf: "00nv",
		Name: "Help",
		Items: map[string]*Item{
			"00nv": &Item{
				name: "Help",
			},
		},
	},
	&Folder{
		Pre: "indx",
		Suf: "00nv",
		Name: "Index",
		Items: map[string]*Item{
			"0001": &Item{
				name: "Index",
				Targets: map[string]Target{
					"0001": R(25,66, 72,114),
					"0002": R(75,70, 119,115),
					"0003": R(122,68, 163,114),
					"0004": R(166,69, 295,115),
					"0005": R(297,66, 389,115),
					"0006": R(394,69, 502,117),
					"0007": R(504,66, 703,115),
					"0008": R(702,66, 791,116),
					"0009": R(794,67, 880,117),
					"0010": R(879,68, 1018,114),
					"0011": R(1013,66, 1210,116),
				},
			},
			"0002": &Item{},
			"0003": &Item{},
			"0004": &Item{},
			"0005": &Item{},
			"0006": &Item{},
			"0007": &Item{},
			"0008": &Item{},
			"0009": &Item{},
			"0010": &Item{},
			"0011": &Item{},
		},
	},
	/*Folder{
		Pre: "titl",
		Suf: "00nv",
		Name: "Title",
		Items: map[string]*Item{
			"00nv": "Title",
		},
	},*/
	&Folder{
		Pre: "weap",
		Suf: "00nv",
		Name: "Index",
		Items: map[string]*Item{
			"00nv": &Item{
				name: "Index",
				Targets: map[string]Target{
					"01pu": C(250, 400, 150),
					"03pu": C(654, 375, 150),
					"02pu": C(1047, 400, 150),
				},
			},
			"01pu": &Item{},
			"03pu": &Item{},
			"02pu": &Item{},
		},
	},
	&Folder{
		Pre: "wwfd",
		Suf: "00aa",
		Name: "WWF",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "WWF",
				Targets: map[string]Target{
					"03pu": C(302, 176, 80),
					"04pu": C(518, 255, 80),
					"02pu": C(685, 415, 80),
					"06pu": C(952, 147, 80),
					"05pu": C(917, 324, 80),
					"01pu": C(1102, 313, 80),
					"07tv": C(202, 465, 80),
					"00fb": C(89, 55, 80),
					"01fb": C(1208, 69, 80),
				},
			},
			"03pu": &Item{},
			"04pu": &Item{},
			"02pu": &Item{},
			"06pu": &Item{},
			"05pu": &Item{},
			"01pu": &Item{},
			"07tv": &Item{},
			"00fb": &Item{},
			"01fb": &Item{},
		},
	},

	/* animal */
	&Folder{
		Category: Animal,
		Pre: "addr",
		Suf: "00aa",
		Name: "European Adder",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "European Adder",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "aant",
		Suf: "00aa",
		Name: "Army Ant",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Army Ant",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "alig",
		Suf: "00aa",
		Name: "Aligator",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Aligator",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "arow",
		Suf: "00aa",
		Name: "Poison Arrow Frog",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Poison Arrow Frog",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "babn",
		Suf: "00aa",
		Name: "Baboon",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Baboon",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "bara",
		Suf: "00aa",
		Name: "Baracuda",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Baracuda",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "boac",
		Suf: "00aa",
		Name: "Boa",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Boa",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "boct",
		Suf: "00aa",
		Name: "Blue-ringed Octopus",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Blue-ringed Octopus",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "bwid",
		Suf: "00aa",
		Name: "Black Widow Spider",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Black Widow Spider",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "cane",
		Suf: "00aa",
		Name: "Cane Toad",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Cane Toad",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "cbuf",
		Suf: "00aa",
		Name: "Cape Buffalo",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Cape Buffalo",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "cdog",
		Suf: "00aa",
		Name: "Cape Hunting Dog",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Cape Hunting Dog",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "cent",
		Suf: "00aa",
		Name: "Centipede",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Centipede",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "chee",
		Suf: "00aa",
		Name: "Cheetah",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Cheetah",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "cobr",
		Suf: "00aa",
		Name: "Cobra",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Cobra",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "cock",
		Suf: "00aa",
		Name: "Cockroach",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Cockroach",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "coug",
		Suf: "00aa",
		Name: "Cougar",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Cougar",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "crab",
		Suf: "00aa",
		Name: "Crab",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Crab",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "croc",
		Suf: "00aa",
		Name: "Crocodile",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Crocodile",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "eeel",
		Suf: "00aa",
		Name: "Electric Eel",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Electric Eel",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "elef",
		Suf: "00aa",
		Name: "Elefant",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Elefant",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "fsal",
		Suf: "00aa",
		Name: "Fire Salamander",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Fire Salamander",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "funl",
		Suf: "00aa",
		Name: "Funnel-web Spider",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Funnel-web Spider",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "gila",
		Suf: "00aa",
		Name: "Gila Monster",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Gila Monster",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "griz",
		Suf: "00aa",
		Name: "Grizzly Bear",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Grizzly Bear",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "gsqu",
		Suf: "00aa",
		Name: "Giant Squid",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Giant Squid",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "gwsh",
		Suf: "00aa",
		Name: "Great White Shark",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Great White Shark",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "gwsh",
		Suf: "00aa",
		Name: "Hammerhead Shark",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Hammerhead Shark",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "harp",
		Suf: "00aa",
		Name: "Harpy Eagle",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Harpy Eagle",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "hipp",
		Suf: "00aa",
		Name: "Hippopotamus",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Hippopotamus",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "hyen",
		Suf: "00aa",
		Name: "Hyena",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Hyena",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "jagu",
		Suf: "00aa",
		Name: "Jaguar",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Jaguar",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "kbee",
		Suf: "00aa",
		Name: "Killer Bee",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Killer Bee",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "komd",
		Suf: "00aa",
		Name: "Komodo Dragon",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Komodo Dragon",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "leop",
		Suf: "00aa",
		Name: "Leopard",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Leopard",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "lfsh",
		Suf: "00aa",
		Name: "Lionfish",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Lionfish",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "lion",
		Suf: "00aa",
		Name: "Lion",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Lion",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "mamb",
		Suf: "00aa",
		Name: "Black Mamba",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Black Mamba",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "mang",
		Suf: "00aa",
		Name: "Mangrove Snake",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Mangrove Snake",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "meel",
		Suf: "00aa",
		Name: "Moray Eel",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Moray Eel",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "mosq",
		Suf: "00aa",
		Name: "Mosquito",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Mosquito",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "mwar",
		Suf: "00aa",
		Name: "Portuguese Man-of-War",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Portuguese Man-of-War",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "orca",
		Suf: "00aa",
		Name: "Killer Whale",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Killer Whale",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "pbea",
		Suf: "00aa",
		Name: "Polar Bear",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Polar Bear",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "pira",
		Suf: "00aa",
		Name: "Piranha",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Piranha",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "plat",
		Suf: "00aa",
		Name: "Platypus",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Platypus",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "porc",
		Suf: "00aa",
		Name: "Porcupine Fish",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Porcupine Fish",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "post",
		Suf: "00aa",
		Name: "Passion-vine Caterpillar",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Passion-vine Caterpillar",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "pyth",
		Suf: "00aa",
		Name: "Python",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Python",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "rats",
		Suf: "00aa",
		Name: "Rats",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Rats",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "rhin",
		Suf: "00aa",
		Name: "Rhinoceros",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Rhinoceros",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "rttl",
		Suf: "00aa",
		Name: "Rattlesnake",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Rattlesnake",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "scor",
		Suf: "00aa",
		Name: "Scorpion",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Scorpion",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "seas",
		Suf: "00aa",
		Name: "Sea Snake",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Sea Snake",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "snap",
		Suf: "00aa",
		Name: "Snapping Turtle",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Snapping Turtle",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "sray",
		Suf: "00aa",
		Name: "Stingray",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Stingray",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "swsp",
		Suf: "00aa",
		Name: "Australian Sea Wasp",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Australian Sea Wasp",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "tasm",
		Suf: "00aa",
		Name: "Tasmanian Devil",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Tasmanian Devil",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "tigr",
		Suf: "00aa",
		Name: "Tiger",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Tiger",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "vamp",
		Suf: "00aa",
		Name: "Vampire Bat",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Vampire Bat",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "vult",
		Suf: "00aa",
		Name: "Vulture",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Vulture",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "wart",
		Suf: "00aa",
		Name: "Warthog",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Warthog",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "wasp",
		Suf: "00aa",
		Name: "Wasp",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Wasp",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "wlvr",
		Suf: "00aa",
		Name: "Wolverine",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Wolverine",
			},
		},
	},
	&Folder{
		Category: Animal,
		Pre: "wolf",
		Suf: "00aa",
		Name: "Wolf",
		Items: map[string]*Item{
			"00aa": &Item{
				name: "Wolf",
			},
		},
	},
}

func init() {
	for _, f := range folders {
		for _, it := range f.Items {
			it.f = f
			if f.Pre == "indx" {
				it.Targets = f.Items["0001"].Targets
			}
		}
	}
}

func check(err error, msg string) {
	if err != nil {
		log.Fatalf("%s: %s\n", msg, err)
	}
}

func resize(img image.Image, scale int) image.Image {
	bounds := img.Bounds()
	newX := bounds.Dx() * scale
	newY:= bounds.Dy() * scale
	dst := image.NewRGBA(image.Rect(0, 0, newX, newY))
	xdraw.NearestNeighbor.Scale(dst, dst.Rect, img, img.Bounds(), xdraw.Over, nil)
	return dst
}

func	readImagePath(path string) *draw.Image {
		bs, err := os.ReadFile(path)
		check(err, "read file")
		data, err := szdd.Expand(bs)
		check(err, "expand")
		img, _, err := image.Decode(bytes.NewReader(data))
		check(err, "decode")
		if scale > 1 {
			img = resize(img, scale)
		}
		bounds := img.Bounds()
		ni, err := dui.Display.AllocImage(bounds, draw.ABGR32, false, draw.White)
		check(err, "allocimage")
		var rgba *image.RGBA
		switch i := img.(type) {
		case *image.RGBA:
			rgba = i
		default:
			b := img.Bounds()
			rgba = image.NewRGBA(image.Rectangle{image.ZP, b.Size()})
			imagedraw.Draw(rgba, rgba.Bounds(), img, b.Min, imagedraw.Src)
		}
		_, err = ni.Load(rgba.Bounds(), rgba.Pix)
		check(err, "load image")
		return ni
	}

func main() {
	sc := flag.Int("x", 0, "scale")
	flag.Parse()
	scale = *sc

	var err error
	dui, err = duit.NewDUI("wildlife", nil)
	check(err, "new dui")

	if scale == 0 {
		if dui.Display.DPI > 100 {
			scale = 2
		} else {
			scale = 1
		}
	}

	f := getFolder("", "cont")
	it := f.Main()
	history = append(history, it)
	dui.Top.UI = it
	dui.Render()

	for {
		select {
		case e := <-dui.Inputs:
			dui.Input(e)

		case err, ok := <-dui.Error:
			if !ok {
				return
			}
			log.Printf("duit: %s\n", err)
		}
	}
}