1// ltr: Layer Tennis remixes
2
3package main
4
5import (
6	"flag"
7	"fmt"
8	"os"
9
10	"github.com/ajstarks/svgo"
11)
12
13var (
14	canvas                            = svg.New(os.Stdout)
15	poster, opacity, row, col, offset bool
16	title                             string
17	width, height                     int
18)
19
20const (
21	stdwidth  = 900
22	stdheight = 280
23	ni        = 11
24)
25
26// imagefiles returns a list of files in the specifed directory
27// or nil on error. Each file includes the prepended directory name
28func imagefiles(directory string) []string {
29	f, ferr := os.Open(directory)
30	if ferr != nil {
31		return nil
32	}
33	defer f.Close()
34	files, derr := f.Readdir(-1)
35	if derr != nil || len(files) == 0 {
36		return nil
37	}
38	names := make([]string, len(files))
39	for i, v := range files {
40		names[i] = directory + "/" + v.Name()
41	}
42	return names
43}
44
45// ltposter creates poster style: a title, followed by a list
46// of volleys
47func ltposter(x, y, w, h int, f []string) {
48	canvas.Image(x, y, w*2, h*2, f[0]) // first file, assumed to be the banner
49	y = y + (h * 2)
50	for i := 1; i < len(f); i += 2 {
51		canvas.Image(x, y, w, h, f[i])
52		canvas.Image(x+w, y, w, h, f[i+1])
53		if i%2 == 1 {
54			y += h
55		}
56	}
57}
58
59// ltcol creates a single column of volley images
60func ltcol(x, y, w, h int, f []string) {
61	for i := 0; i < len(f); i++ {
62		canvas.Image(x, y, w, h, f[i])
63		y += h
64	}
65}
66
67// ltop creates a view with each volley stacked together with
68// semi-transparent opacity
69func ltop(x, y, w, h int, f []string) {
70	for i := 1; i < len(f); i++ { // skip the first file, assumed to be the banner
71		canvas.Image(x, y, w, h, f[i], "opacity:0.2")
72	}
73}
74
75// ltrow creates a row-wise view of volley images.
76func ltrow(x, y, w, h int, f []string) {
77	for i := 0; i < len(f); i++ {
78		canvas.Image(x, y, w, h, f[i])
79		x += w
80	}
81}
82
83// ltoffset creates a view where each volley is offset from its opposing volley.
84func ltoffset(x, y, w, h int, f []string) {
85	for i := 1; i < len(f); i++ { // skip the first file, assumed to be the banner
86
87		if i%2 == 0 {
88			x += w
89		} else {
90			x = 0
91		}
92		canvas.Image(x, y, w, h, f[i])
93		y += h
94	}
95}
96
97// dotitle creates the title
98func dotitle(s string) {
99	if len(title) > 0 {
100		canvas.Title(title)
101	} else {
102		canvas.Title(s)
103	}
104}
105
106// init sets up the command line flags.
107func init() {
108	flag.BoolVar(&poster, "poster", false, "poster style")
109	flag.BoolVar(&opacity, "opacity", false, "opacity style")
110	flag.BoolVar(&row, "row", false, "display is a single row")
111	flag.BoolVar(&col, "col", false, "display in a single column")
112	flag.BoolVar(&offset, "offset", false, "display in a row, even layers offset")
113	flag.IntVar(&width, "width", stdwidth, "image width")
114	flag.IntVar(&height, "height", stdheight, "image height")
115	flag.StringVar(&title, "title", "", "title")
116	flag.Parse()
117}
118
119func main() {
120	x := 0
121	y := 0
122	nd := len(flag.Args())
123	for i, dir := range flag.Args() {
124		filelist := imagefiles(dir)
125		if len(filelist) != ni || filelist == nil {
126			fmt.Fprintf(os.Stderr, "in the %s directory, need %d images, read %d\n", dir, ni, len(filelist))
127			continue
128		}
129		switch {
130
131		case opacity:
132			if i == 0 {
133				canvas.Start(width*nd, height*nd)
134				dotitle(dir)
135			}
136			ltop(x, y, width, height, filelist)
137			y += height
138
139		case poster:
140			if i == 0 {
141				canvas.Start(width, ((height*(ni-1)/4)+height)*nd)
142				dotitle(dir)
143			}
144			ltposter(x, y, width/2, height/2, filelist)
145			y += (height * 3) + (height / 2)
146
147		case col:
148			if i == 0 {
149				canvas.Start(width*nd, height*ni)
150				dotitle(dir)
151			}
152			ltcol(x, y, width, height, filelist)
153			x += width
154
155		case row:
156			if i == 0 {
157				canvas.Start(width*ni, height*nd)
158				dotitle(dir)
159			}
160			ltrow(x, y, width, height, filelist)
161			y += height
162
163		case offset:
164			n := ni - 1
165			pw := width * 2
166			ph := nd * (height * (n))
167			if i == 0 {
168				canvas.Start(pw, ph)
169				canvas.Rect(0, 0, pw, ph, "fill:white")
170				dotitle(dir)
171			}
172			ltoffset(x, y, width, height, filelist)
173			y += n * height
174
175		}
176	}
177	canvas.End()
178}
179