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 126 // check if database id matches 127 if (id != null && other.id != null) { 128 return id.equals(other.id) && Objects.equals(seriesInfo, other.seriesInfo); 129 } 130 131 // check if episode record matches 132 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); 133 } 134 135 return false; 136 } 137 138 @Override 139 public int hashCode() { 140 return id != null ? id : Objects.hash(season, episode, absolute, special, seriesName, title); 141 } 142 143 @Override 144 public Episode clone() { 145 return new Episode(this); 146 } 147 148 public Episode number(Integer episode) { 149 return new Episode(getSeriesName(), null, episode, getTitle(), null, null, getAirdate(), getRuntime(), getId(), getGroup(), getSeriesInfo()); 150 } 151 152 public Episode number(Integer season, Integer episode) { 153 return new Episode(getSeriesName(), season, episode, getTitle(), null, null, getAirdate(), getRuntime(), getId(), getGroup(), getSeriesInfo()); 154 } 155 156 public Episode number(Integer season, Integer episode, Integer absolute) { 157 return new Episode(getSeriesName(), season, episode, getTitle(), absolute, null, getAirdate(), getRuntime(), getId(), getGroup(), getSeriesInfo()); 158 } 159 160 public Episode title(String title) { 161 return new Episode(getSeriesName(), getSeason(), getEpisode(), title, getAbsolute(), getSpecial(), getAirdate(), getRuntime(), getId(), getGroup(), getSeriesInfo()); 162 } 163 164 public Episode group(String group) { 165 return new Episode(getSeriesName(), getSeason(), getEpisode(), getTitle(), getAbsolute(), getSpecial(), getAirdate(), getRuntime(), getId(), group, getSeriesInfo()); 166 } 167 168 public Episode absolute(Integer absolute) { 169 return new Episode(getSeriesName(), getSeason(), getEpisode(), getTitle(), absolute, getSpecial(), getAirdate(), getRuntime(), getId(), getGroup(), getSeriesInfo()); 170 } 171 172 public Episode airdate(String date) { 173 return new Episode(getSeriesName(), getSeason(), getEpisode(), getTitle(), getAbsolute(), getSpecial(), SimpleDate.parse(date), getRuntime(), getId(), getGroup(), getSeriesInfo()); 174 } 175 176 public Episode airdate(int year, int month, int day) { 177 return new Episode(getSeriesName(), getSeason(), getEpisode(), getTitle(), getAbsolute(), getSpecial(), SimpleDate.of(year, month, day), getRuntime(), getId(), getGroup(), getSeriesInfo()); 178 } 179 180 public Episode derive(Integer season, Integer episode) { 181 return derive(getSeriesName(), season, episode, null, null, null); 182 } 183 184 public Episode derive(Integer absolute) { 185 return derive(getSeriesName(), null, absolute, null, absolute, null); 186 } 187 188 public Episode derive(String seriesName, Integer season, Integer episode, String title, Integer absolute, SimpleDate airdate) { 189 return new Episode(seriesName, season, episode, title, absolute, null, airdate, null, null, null, null); 190 } 191 192 public MappedEpisode map(Episode mapping) { 193 return new MappedEpisode(this, mapping); 194 } 195 196 public MappedEpisode map(List<Episode> mapping) { 197 switch (mapping.size()) { 198 case 0: 199 return null; 200 case 1: 201 return new MappedEpisode(this, mapping.get(0)); 202 default: 203 return new MappedEpisode(this, new MultiEpisode(mapping)); 204 } 205 } 206 207 @Override 208 public String toString() { 209 return EpisodeFormat.DEFAULT.format(this); 210 } 211 212}