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