001package com.fs.starfarer.api.util;
002
003import java.awt.Color;
004import java.util.Iterator;
005import java.util.LinkedHashMap;
006import java.util.Map;
007
008public class ColorShifterUtil implements ColorShifterAPI {
009        
010        public static class ShiftData2 {
011                public Color to;
012                public FaderUtil fader;
013                public float shift;
014                public boolean nudged;
015        }
016        
017        protected Color base;
018        protected Color curr;
019        protected boolean useSquareOfProgress = true;
020        protected Map<Object, ShiftData2> data = new LinkedHashMap<Object, ShiftData2>();
021
022        public ColorShifterUtil(Color base) {
023                this.base = base;
024                this.curr = base;
025        }
026        
027        public boolean isUseSquareOfProgress() {
028                return useSquareOfProgress;
029        }
030
031        public void setUseSquareOfProgress(boolean useSquareOfProgress) {
032                this.useSquareOfProgress = useSquareOfProgress;
033        }
034
035        public Color getBase() {
036                return base;
037        }
038
039        public void setBase(Color base) {
040                this.base = base;
041        }
042        
043        public Color getCurr() {
044                return curr;
045        }
046
047        public void shift(Object source, Color to, float durIn, float durOut, float shift) {
048                if (to == null) {
049                        data.remove(source);
050                        return;
051                }
052                ShiftData2 sd = data.get(source);
053                if (sd == null) {
054                        sd = new ShiftData2();
055                        sd.fader = new FaderUtil(0, durIn, durOut);
056                        sd.fader.setBounceDown(true);
057                        data.put(source, sd);
058                }
059                sd.to = to;
060                sd.shift = shift;
061                sd.fader.setDuration(durIn, durOut);
062                sd.fader.fadeIn();
063                sd.nudged = true;
064        }
065        
066        public void advance(float amount) {
067                Iterator<ShiftData2> iter = data.values().iterator();
068                while (iter.hasNext()) {
069                        ShiftData2 sd = iter.next();
070                        if (!sd.nudged) sd.fader.fadeOut();
071                        sd.nudged = false;
072                        sd.fader.advance(amount);
073                        if (sd.fader.isFadedOut()) {
074                                iter.remove();
075                        }
076                }
077                updateCurr();
078        }
079        
080        public boolean isShifted() {
081                //return curr != base;
082                return !data.isEmpty();
083        }
084        
085        protected void updateCurr() {
086                if (data.isEmpty()) {
087                        curr = base;
088                        return;
089                }
090                curr = getCurrForBase(base);
091        }
092        
093        public Color getCurrForBase(Color diffBase) {
094                if (data == null || data.isEmpty()) {
095                        return diffBase;
096                }
097                
098                float totalWeight = 0f;
099                for (ShiftData2 sd : data.values()) {
100                        float progress = sd.fader.getBrightness();
101                        if (useSquareOfProgress) progress *= progress;
102                        totalWeight += progress;
103                }
104//              totalWeight = data.size();
105                
106                if (totalWeight <= 0) {
107                        return diffBase;
108                }
109                
110                float red = (float)diffBase.getRed();
111                float green = (float)diffBase.getGreen();
112                float blue = (float)diffBase.getBlue();
113                float alpha = (float)diffBase.getAlpha();
114                
115                for (ShiftData2 sd : data.values()) {
116                        float progress = sd.fader.getBrightness();
117                        if (useSquareOfProgress) progress *= progress;
118                        float currWeight = totalWeight - progress + 1f;
119                        red += ((float)sd.to.getRed() - (float)diffBase.getRed()) * sd.shift * progress / currWeight;
120                        green += ((float)sd.to.getGreen() - (float)diffBase.getGreen()) * sd.shift * progress / currWeight;
121                        blue += ((float)sd.to.getBlue() - (float)diffBase.getBlue()) * sd.shift * progress / currWeight;
122                        alpha += ((float)sd.to.getAlpha() - (float)diffBase.getAlpha()) * sd.shift * progress / currWeight;
123                }
124                
125                if (red > 255) red = 255;
126                if (green > 255) green = 255;
127                if (blue > 255) blue = 255;
128                if (alpha > 255) alpha = 255;
129                if (red < 0) red = 0;
130                if (green < 0) green = 0;
131                if (blue < 0) blue = 0;
132                if (alpha < 0) alpha = 0;
133                
134                return new Color((int)red, (int)green, (int)blue, (int)alpha);
135        }
136        
137        public static void main(String[] args) {
138                ColorShifterUtil c = new ColorShifterUtil(Color.red);
139                
140                for (int i = 0; i < 10; i++) {
141                        c.shift("c1", Color.green, 1f, 1f, 1f);
142                        c.shift("c2", Color.blue, 1f, 1f, 0.5f);
143                        c.advance(0.1f);
144                }
145                
146                System.out.println(c.getCurr());
147
148//              c.advance(0.1f);
149//              System.out.println(c.getCurr());
150        }
151        
152}
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169