]> git.lizzy.rs Git - go-anidb.git/blob - misc/episodelist.go
877ac4a9ea86e82a4ec722d2125df597fc5f39e4
[go-anidb.git] / misc / episodelist.go
1 package misc
2
3 import (
4         "fmt"
5         "sort"
6         "strings"
7 )
8
9 type EpisodeList []*EpisodeRange
10
11 // Converts the EpisodeList into the AniDB API list format.
12 func (el EpisodeList) String() string {
13         scales := map[EpisodeType]int{}
14
15         for _, er := range el {
16                 if er == nil {
17                         continue
18                 }
19
20                 s := er.scale()
21                 if s > scales[er.Type] {
22                         scales[er.Type] = s
23                 }
24         }
25
26         parts := make([]string, len(el))
27         for i, er := range el {
28                 parts[i] = er.Format(scales[er.Type])
29         }
30
31         return strings.Join(parts, ",")
32 }
33
34 // Returns true if any of the contained EpisodeRanges contain the
35 // given EpisodeContainer.
36 func (el EpisodeList) ContainsEpisodes(ec EpisodeContainer) bool {
37         for _, i := range el {
38                 if i != nil && i.ContainsEpisodes(ec) {
39                         return true
40                 }
41         }
42         return false
43 }
44
45 // Parses a string in the AniDB API list format and converts into
46 // an EpisodeList.
47 //
48 //      ParseEpisodeList("01")       <=> EpisodeList{ParseEpisodeRange("01")}
49 //      ParseEpisodeList("S2-S3")    <=> EpisodeList{ParseEpisodeRange("S2-S3")}
50 //      ParseEpisodeList("T1,C1-C3") <=> EpisodeList{ParseEpisodeRange("T1"), ParseEpisodeRange("C1-C3")}
51 func ParseEpisodeList(s string) (el EpisodeList) {
52         parts := strings.Split(s, ",")
53
54         el = make(EpisodeList, len(parts))
55         for i := range parts {
56                 el[i] = ParseEpisodeRange(parts[i])
57         }
58
59         return
60 }
61
62 // Returns a simplified version of the EpisodeList (removes nil ranges, merges mergeable ranges, sorts).
63 func (el EpisodeList) Simplify() EpisodeList {
64         nl := make(EpisodeList, 0, len(el))
65
66         // drop nil ranges
67         for _, er := range el {
68                 if er != nil {
69                         nl = append(nl, er)
70                 }
71         }
72
73         // merge ranges
74         for n, changed := 0, true; changed; n++ {
75                 tmp := EpisodeList{}
76                 used := map[int]bool{}
77                 changed = false
78
79                 for i, a := range nl {
80                         if used[i] {
81                                 continue
82                         }
83                         for j, b := range nl[i+1:] {
84                                 if c := a.Merge(b); c != nil {
85                                         changed = true
86                                         used[j+i+1] = true
87                                         a = c
88                                 }
89                         }
90                         tmp = append(tmp, a)
91                 }
92                 nl = tmp
93
94                 if n > len(el) {
95                         panic(fmt.Sprintf("Too many iterations (%d) when simplifing %s!", n, el))
96                 }
97         }
98         sort.Sort(nl)
99         return nl
100 }
101
102 func (el EpisodeList) Len() int {
103         return len(el)
104 }
105
106 func (el EpisodeList) Less(i, j int) bool {
107         switch {
108         case el[i] == nil:
109                 return true
110         case el[j] == nil:
111                 return false
112         case el[i].Type < el[j].Type:
113                 return true
114         case el[i].Type > el[j].Type:
115                 return false
116         case el[i].Start.Number < el[j].Start.Number:
117                 return true
118         }
119         return false
120 }
121
122 func (el EpisodeList) Swap(i, j int) {
123         el[i], el[j] = el[j], el[i]
124 }