001package net.filebot.web;
002
003import static java.util.Arrays.*;
004
005import java.io.Serializable;
006import java.util.ArrayList;
007import java.util.List;
008import java.util.Objects;
009
010public class Episode implements Serializable {
011
012        // base episode record
013        protected String seriesName;
014        protected Integer season;
015        protected Integer episode;
016        protected String title;
017
018        // absolute episode number
019        protected Integer absolute;
020
021        // special number
022        protected Integer special;
023
024        // episode airdate
025        protected SimpleDate airdate;
026
027        // unique identifier
028        protected Integer id;
029
030        // extended series metadata
031        protected String group;
032        protected SeriesInfo seriesInfo;
033
034        public Episode() {
035                // used by deserializer
036        }
037
038        public Episode(Episode other) {
039                this(other.seriesName, other.season, other.episode, other.title, other.absolute, other.special, other.airdate, other.id, other.group, other.seriesInfo);
040        }
041
042        public Episode(String seriesName, Integer season, Integer episode, String title) {
043                this(seriesName, season, episode, title, null, null, null, null, null, null);
044        }
045
046        public Episode(String seriesName, Integer season, Integer episode, String title, Integer absolute, Integer special, SimpleDate airdate, Integer id, String group, SeriesInfo seriesInfo) {
047                this.seriesName = seriesName;
048                this.season = season;
049                this.episode = episode;
050                this.title = title;
051                this.absolute = absolute;
052                this.special = special;
053                this.airdate = airdate == null ? null : airdate.clone();
054                this.id = id;
055                this.group = group;
056                this.seriesInfo = seriesInfo == null ? null : seriesInfo.clone();
057        }
058
059        public String getSeriesName() {
060                return seriesName;
061        }
062
063        public Integer getEpisode() {
064                return episode;
065        }
066
067        public Integer getSeason() {
068                return season;
069        }
070
071        public String getTitle() {
072                return title;
073        }
074
075        public Integer getAbsolute() {
076                return absolute;
077        }
078
079        public Integer getSpecial() {
080                return special;
081        }
082
083        public SimpleDate getAirdate() {
084                return airdate;
085        }
086
087        public Integer getId() {
088                return id;
089        }
090
091        public String getGroup() {
092                return group;
093        }
094
095        public SeriesInfo getSeriesInfo() {
096                return seriesInfo;
097        }
098
099        public List<String> getSeriesNames() {
100                List<String> names = new ArrayList<String>();
101                if (seriesName != null) {
102                        names.add(seriesName);
103                }
104                if (seriesInfo != null) {
105                        if (seriesInfo.name != null && !seriesInfo.name.equals(seriesName)) {
106                                names.add(seriesInfo.name);
107                        }
108                        if (seriesInfo.aliasNames != null) {
109                                names.addAll(asList(seriesInfo.aliasNames));
110                        }
111                }
112                return names;
113        }
114
115        @Override
116        public boolean equals(Object obj) {
117                if (obj instanceof Episode) {
118                        Episode other = (Episode) obj;
119
120                        // check if database id matches
121                        if (id != null && other.id != null) {
122                                return id.equals(other.id) && Objects.equals(seriesInfo, other.seriesInfo);
123                        }
124
125                        // check if episode record matches
126                        return Objects.equals(season, other.season) && Objects.equals(episode, other.episode) && Objects.equals(absolute, other.absolute) && Objects.equals(special, other.special) && Objects.equals(seriesName, other.seriesName) && Objects.equals(title, other.title) && Objects.equals(group, other.group);
127                }
128
129                return false;
130        }
131
132        @Override
133        public int hashCode() {
134                return id != null ? id : Objects.hash(season, episode, absolute, special, seriesName, title);
135        }
136
137        @Override
138        public Episode clone() {
139                return new Episode(this);
140        }
141
142        public Episode number(Integer episode) {
143                return new Episode(getSeriesName(), null, episode, getTitle(), null, null, getAirdate(), getId(), getGroup(), getSeriesInfo());
144        }
145
146        public Episode number(Integer season, Integer episode) {
147                return new Episode(getSeriesName(), season, episode, getTitle(), null, null, getAirdate(), getId(), getGroup(), getSeriesInfo());
148        }
149
150        public Episode number(Integer season, Integer episode, Integer absolute) {
151                return new Episode(getSeriesName(), season, episode, getTitle(), absolute, null, getAirdate(), getId(), getGroup(), getSeriesInfo());
152        }
153
154        public Episode title(String title) {
155                return new Episode(getSeriesName(), getSeason(), getEpisode(), title, getAbsolute(), getSpecial(), getAirdate(), getId(), getGroup(), getSeriesInfo());
156        }
157
158        public Episode group(String group) {
159                return new Episode(getSeriesName(), getSeason(), getEpisode(), getTitle(), getAbsolute(), getSpecial(), getAirdate(), getId(), group, getSeriesInfo());
160        }
161
162        public Episode absolute(Integer absolute) {
163                return new Episode(getSeriesName(), getSeason(), getEpisode(), getTitle(), absolute, getSpecial(), getAirdate(), getId(), getGroup(), getSeriesInfo());
164        }
165
166        public Episode airdate(String date) {
167                return new Episode(getSeriesName(), getSeason(), getEpisode(), getTitle(), getAbsolute(), getSpecial(), SimpleDate.parse(date), getId(), getGroup(), getSeriesInfo());
168        }
169
170        public Episode airdate(int year, int month, int day) {
171                return new Episode(getSeriesName(), getSeason(), getEpisode(), getTitle(), getAbsolute(), getSpecial(), SimpleDate.of(year, month, day), getId(), getGroup(), getSeriesInfo());
172        }
173
174        public Episode derive(Integer season, Integer episode) {
175                return derive(getSeriesName(), season, episode, null, null, null);
176        }
177
178        public Episode derive(Integer absolute) {
179                return derive(getSeriesName(), null, absolute, null, absolute, null);
180        }
181
182        public Episode derive(String seriesName, Integer season, Integer episode, String title, Integer absolute, SimpleDate airdate) {
183                return new Episode(seriesName, season, episode, title, absolute, null, airdate, null, null, null);
184        }
185
186        public MappedEpisode map(Episode mapping) {
187                return new MappedEpisode(this, mapping);
188        }
189
190        public MappedEpisode map(List<Episode> mapping) {
191                switch (mapping.size()) {
192                case 0:
193                        return null;
194                case 1:
195                        return new MappedEpisode(this, mapping.get(0));
196                default:
197                        return new MappedEpisode(this, new MultiEpisode(mapping));
198                }
199        }
200
201        @Override
202        public String toString() {
203                return EpisodeFormat.DEFAULT.format(this);
204        }
205
206}