1package wallutils
2
3import (
4	"errors"
5	"fmt"
6	"path/filepath"
7	"strconv"
8	"strings"
9)
10
11// Res is a structure containing width and height
12type Res struct {
13	w, h uint
14}
15
16// NewRes creates a new resolution structure
17func NewRes(w, h uint) *Res {
18	return &Res{w, h}
19}
20
21func (r *Res) String() string {
22	return fmt.Sprintf("%dx%d", r.w, r.h)
23}
24
25// W is the width
26func (r *Res) W() uint {
27	return r.w
28}
29
30// H is the height
31func (r *Res) H() uint {
32	return r.h
33}
34
35// Distance returns the distance between two resolutions (Euclidean distance)
36func Distance(a, b *Res) int {
37	return abs(int(b.w)-int(a.w)) + abs(int(b.h)-int(a.h))
38}
39
40// ParseSize parses a string on the form "1234x1234"
41func ParseSize(widthHeight string) (uint, uint, error) {
42	fields := strings.SplitN(strings.ToLower(widthHeight), "x", 2)
43	w, err := strconv.Atoi(fields[0])
44	if err != nil {
45		return 0, 0, err
46	}
47	h, err := strconv.Atoi(fields[1])
48	if err != nil {
49		return 0, 0, err
50	}
51	return uint(w), uint(h), nil
52}
53
54// FilenameToRes extracts width and height from a filename on the form: "asdf_123x123.xyz",
55// or filenames that are just on the form "123x123.xyz".
56func FilenameToRes(filename string) (*Res, error) {
57	size := firstname(filepath.Base(filename))
58	if strings.Contains(size, "_") {
59		parts := strings.Split(size, "_")
60		size = parts[len(parts)-1]
61	}
62	if !strings.Contains(size, "x") {
63		return nil, errors.New("does not contain width x height: " + filename)
64	}
65	width, height, err := ParseSize(size)
66	if err != nil {
67		return nil, fmt.Errorf("does not contain width x height: %s: %s", filename, err)
68	}
69	return &Res{uint(width), uint(height)}, nil
70}
71
72// ExtractResolutions extracts Res structs from a slice of filenames
73// All the filenames must be on the form *_WIDTHxHEIGHT.ext,
74// where WIDTH and HEIGHT are numbers.
75func ExtractResolutions(filenames []string) ([]*Res, error) {
76	var resolutions []*Res
77	for _, filename := range filenames {
78		res, err := FilenameToRes(filename)
79		if err != nil {
80			return resolutions, err
81		}
82		resolutions = append(resolutions, res)
83	}
84	return resolutions, nil
85}
86