001package com.fs.starfarer.api.impl.campaign.events;
002
003import com.fs.starfarer.api.Global;
004import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
005import com.fs.starfarer.api.campaign.econ.MarketAPI;
006import com.fs.starfarer.api.campaign.events.CampaignEventPlugin.PriceUpdatePlugin;
007import com.fs.starfarer.api.impl.campaign.shared.CommodityStatTracker;
008import com.fs.starfarer.api.util.Misc;
009
010public class PriceUpdate implements PriceUpdatePlugin {
011        
012        private String marketId;
013        private String commodityId;
014        private float supplyPrice;
015        private float demandPrice;
016        private PriceType type;
017        private long timestamp;
018        private float demand;//, available;
019        public PriceUpdate(CommodityOnMarketAPI commodity) {
020                //this.commodity = commodity;
021                marketId = commodity.getMarket().getId();
022                commodityId = commodity.getId();
023                supplyPrice = Math.round(commodity.getMarket().getSupplyPrice(commodity.getId(), 1, true));
024                demandPrice = Math.round(commodity.getMarket().getDemandPrice(commodity.getId(), 1, true));
025                //priceMult = commodity.getPlayerPriceMult().getModifiedValue();
026                
027//              if (commodityId.equals("food")) {
028//                      System.out.println("dsfsdfsdf");
029//              }
030                updateType();
031                timestamp = Global.getSector().getClock().getTimestamp();
032                
033//              float f = Global.getSettings().getFloat("economyAverageFractionOfStockpilePlayerCanBuy");
034//              available = commodity.getAverageStockpileAfterDemand() * f;
035                demand  = commodity.getDemand().getDemandValue();
036        }
037        
038        public void updatePrices(float stockpileMult) {
039                CommodityOnMarketAPI com = getCommodity();
040                float stockpile = com.getStockpile();
041                float after = stockpile * stockpileMult;
042                
043                float diff = (after - stockpile) * com.getUtilityOnMarket();
044                
045                supplyPrice = Math.round(com.getMarket().getSupplyPriceAssumingExistingTransaction(
046                                com.getId(), 1, diff, true));
047                demandPrice = Math.round(com.getMarket().getDemandPriceAssumingExistingTransaction(
048                                com.getId(), 1, diff, true));
049                
050        }
051        
052        
053        public int getRoundedPriceForDisplay() {
054                return getRoundedPriceForDisplay(0, 0);
055        }
056        
057        /**
058         * Only call this method when the bonus you want to ignore is not already applied.
059         * @param priceFlat
060         * @param pricePercent
061         * @return
062         */
063        public int getRoundedPriceForDisplay(float priceFlat, float pricePercent) {
064                float testSupplyPrice = supplyPrice;
065                float testDemandPrice = demandPrice;
066                //getCommodity().getMarket().getDemandPrice(getCommodity().getId(), 1, true)
067                // if params are non-0, then the curr price may already include a player-facing modifier - so, discount it
068                // this won't work for multiple sources modifying the same price, though
069                // never mind that - only call this method when the bonus you want to ignore is not already applied.
070                if (priceFlat != 0 || pricePercent != 0) {
071                        CommodityOnMarketAPI commodity = getCommodity();
072                        testSupplyPrice = Math.round(commodity.getMarket().getSupplyPrice(commodity.getId(), 1, true) * (1f + pricePercent / 100f) + priceFlat);
073                        testDemandPrice = Math.round(commodity.getMarket().getDemandPrice(commodity.getId(), 1, true) * (1f + pricePercent / 100f) + priceFlat);
074                }
075                if (true) {
076                        // for now, cheat and grab real prices from market
077                        CommodityOnMarketAPI commodity = getCommodity();
078//                      if (commodity.getId().equals(Commodities.HAND_WEAPONS) && commodity.getMarket().getId().equals("ogma")) {
079//                              System.out.println("q23sdfsdf");
080//                      }
081                        testSupplyPrice = Math.round(commodity.getMarket().getSupplyPrice(commodity.getId(), 1, true));
082                        testDemandPrice = Math.round(commodity.getMarket().getDemandPrice(commodity.getId(), 1, true));
083                        
084                        supplyPrice = testSupplyPrice;
085                        demandPrice = testDemandPrice;
086                        updateType();
087                }
088                
089                int amt = 0;
090                switch (getType()) {
091                case NORMAL:
092                        amt = (int) (testSupplyPrice + testDemandPrice) / 2;
093                        break;
094                case CHEAP:
095                        amt = (int) testSupplyPrice;
096                        break;
097                case EXPENSIVE:
098                        amt = (int) testDemandPrice;
099                        break;
100                }
101                amt = (int) Misc.getRounded(amt);
102                return amt;
103        }
104        
105        
106        
107        public float getDemand() {
108                return demand;
109        }
110
111        public float getAvailable() {
112                //float f = Global.getSettings().getFloat("economyAverageFractionOfStockpilePlayerCanBuy");
113                CommodityOnMarketAPI com = getMarket().getCommodityData(commodityId);
114                //float available = com.getMaxPlayerFacingStockpile(f, com.getAverageStockpileAfterDemand());
115                float available = com.getStockpile();
116                return available;
117        }
118
119        public void updateType() {
120                updateType(0f, 0f);
121        }
122        
123        /**
124         * Only call this method when the bonus you want to ignore is not already applied.
125         * @param priceFlat
126         * @param pricePercent
127         * @return
128         */
129        public void updateType(float priceFlat, float pricePercent) {
130                CommodityOnMarketAPI commodity = getCommodity();
131                //CommodityStatTracker stats = SharedData.getData().getActivityTracker().getCommodityTracker();
132                CommodityStatTracker stats = new CommodityStatTracker();
133                float testSupplyPrice = supplyPrice;
134                float testDemandPrice = demandPrice;
135                
136                // if params are non-0, then the curr price may already include a player-facing modifier - so, discount it
137                // this won't work for multiple sources modifying the same price, though
138                // never mind - only call this method when the bonus you want to ignore is not already applied.
139                if (priceFlat != 0 || pricePercent != 0) {
140                        testSupplyPrice = Math.round(commodity.getMarket().getSupplyPrice(commodity.getId(), 1, true) * (1f + pricePercent / 100f) + priceFlat);
141                        testDemandPrice = Math.round(commodity.getMarket().getDemandPrice(commodity.getId(), 1, true) * (1f + pricePercent / 100f) + priceFlat);
142                }
143                
144                if (stats.isSupplyPriceSignificant(commodity, Misc.getRounded(testSupplyPrice))) {
145                        type = PriceType.CHEAP;
146                } else if (stats.isDemandPriceSignificant(commodity, Misc.getRounded(testDemandPrice))) {
147                        type = PriceType.EXPENSIVE;
148                } else {
149                        type = PriceType.NORMAL;
150                }
151        }
152        
153        public long getTimestamp() {
154                return timestamp;
155        }
156        
157        /**
158         * Checks whether supply/demand is non-trivial.
159         * @return
160         */
161        public boolean isSignificant() {
162                return isSignificant(0f, 0f);
163        }
164        
165        /**
166         * Checks whether supply/demand is non-trivial.
167         * @param priceMult
168         * @return
169         */
170        public boolean isSignificant(float priceFlat, float pricePercent) {
171                updateType(priceFlat, pricePercent);
172                CommodityOnMarketAPI commodity = getCommodity();
173                if ((getType() == PriceType.CHEAP)
174                                && commodity.getStockpile() < 100) return false;
175                
176                if ((getType() == PriceType.NORMAL)
177                                && commodity.getStockpile() + commodity.getDemand().getDemandValue() < 100) return false;
178                
179                if (getType() == PriceType.EXPENSIVE && commodity.getDemand().getDemandValue() < 100) return false;
180                
181                return true;
182        }
183        
184        public MarketAPI getMarket() {
185                return Global.getSector().getEconomy().getMarket(marketId);
186        }
187        public CommodityOnMarketAPI getCommodity() {
188                MarketAPI market = getMarket();
189                if (market == null) return null;
190                return market.getCommodityData(commodityId);
191        }
192        public float getSupplyPrice() {
193                return supplyPrice;
194        }
195        public float getDemandPrice() {
196                return demandPrice;
197        }
198        public PriceType getType() {
199                return type;
200        }
201}