001package net.filebot.web;
002
003import java.util.List;
004import java.util.function.Function;
005
006public class MappedEpisode extends Episode {
007
008        protected Episode original;
009        protected Episode mapping;
010
011        public MappedEpisode() {
012                // used by deserializer
013        }
014
015        public MappedEpisode(Episode original, Episode mapping) {
016                super(original);
017                this.original = unmap(original, MappedEpisode::getOriginal);
018                this.mapping = unmap(mapping, MappedEpisode::getMapping);
019        }
020
021        public Episode getOriginal() {
022                return original;
023        }
024
025        public Episode getMapping() {
026                return mapping;
027        }
028
029        private <T> T getFirst(Function<Episode, T> getter) {
030                T value = getter.apply(mapping);
031                if (value != null) {
032                        return value;
033                }
034                return getter.apply(original);
035        }
036
037        @Override
038        public String getSeriesName() {
039                return getFirst(Episode::getSeriesName);
040        }
041
042        @Override
043        public Integer getEpisode() {
044                return mapping.getEpisode(); // always use mapped episode number
045        }
046
047        @Override
048        public Integer getSeason() {
049                return mapping.getSeason(); // always use mapped season number
050        }
051
052        @Override
053        public String getTitle() {
054                return mapping.getTitle(); // always use mapped episode title
055        }
056
057        @Override
058        public Integer getAbsolute() {
059                return mapping.getAbsolute(); // always use mapped absolute number
060        }
061
062        @Override
063        public Integer getSpecial() {
064                return mapping.getSpecial(); // always use mapped special number
065        }
066
067        @Override
068        public SimpleDate getAirdate() {
069                return mapping.getAirdate(); // always use mapped episode airdate
070        }
071
072        @Override
073        public Integer getId() {
074                return getFirst(Episode::getId);
075        }
076
077        @Override
078        public List<String> getSeriesNames() {
079                return getFirst(Episode::getSeriesNames);
080        }
081
082        @Override
083        public boolean equals(Object obj) {
084                return super.equals(obj); // use original episode object for episode comparison
085        }
086
087        @Override
088        public int hashCode() {
089                return super.hashCode(); // use original episode object for episode comparison
090        }
091
092        @Override
093        public MappedEpisode clone() {
094                return new MappedEpisode(original, mapping);
095        }
096
097        @Override
098        public MappedEpisode derive(Integer season, Integer episode) {
099                return new MappedEpisode(original, mapping.derive(season, episode));
100        }
101
102        @Override
103        public MappedEpisode derive(String seriesName, Integer season, Integer episode, String title, Integer absolute, SimpleDate airdate) {
104                return new MappedEpisode(original, mapping.derive(seriesName, season, episode, title, absolute, airdate));
105        }
106
107        public MappedEpisode reverse() {
108                return new MappedEpisode(mapping, original);
109        }
110
111        public MappedEpisode flatten() {
112                return new MappedEpisode(mapping, mapping);
113        }
114
115        @Override
116        public String toString() {
117                return mapping + " => " + original;
118        }
119
120        private static Episode unmap(Episode episode, Function<MappedEpisode, Episode> original) {
121                while (episode instanceof MappedEpisode) {
122                        MappedEpisode mapping = (MappedEpisode) episode;
123                        episode = original.apply(mapping);
124                }
125                return episode;
126        }
127
128}