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