001 package market;
002
003 import java.awt.Rectangle;
004 import java.io.IOException;
005 import java.util.ArrayList;
006 import java.util.Calendar;
007 import java.util.Iterator;
008 import java.util.List;
009
010 import javax.swing.JFrame;
011
012 import log.Log;
013 import market.event.MarketEventListener;
014 import market.resource.IconSetter;
015 import market.statistics.CCompleteStats;
016 import market.statistics.CCustomerStats;
017 import market.statistics.CISalesStats;
018 import market.statistics.CSalesStats;
019 import market.statistics.Statistics;
020 import sale.Action;
021 import sale.MenuSheet;
022 import sale.MenuSheetItem;
023 import sale.SaleProcess;
024 import sale.SalesPoint;
025 import sale.Shop;
026 import sale.StepTimer;
027 import sale.Time;
028 import data.Catalog;
029 import data.CountingStock;
030 import data.IntegerValue;
031 import data.Value;
032 import data.ooimpl.CatalogImpl;
033 import data.ooimpl.StoringStockImpl;
034
035 /**
036 * The Shop of this sale-application.
037 */
038 public class SMarket extends Shop {
039
040 /**
041 * ID for serialization.
042 */
043 private static final long serialVersionUID = 8972722234332831551L;
044
045 public static final String CAT_ARTICLECATALOG = "Produktkatalog";
046 public static final String CAT_OPENPURCHASE = "Erwartete Lieferungen";
047 public static final String CAT_CUSTOMER = "Kunden";
048 public static final String CAT_COMPLETE_SALESSTATS = "Komplette Statistik";
049 public static final String STK_OFFER = "Angebot";
050 public static final String STK_TILLQUEUE = "Kunden-Warteschlange";
051 public static final String STK_WAREHOUSEQUEUE = "Auftrags-Warteschlange";
052 public static final String MARKET_CLOSES_SHORT = "ACHTUNG: Der Markt schließt jetzt.";
053 public static final String MARKET_CLOSES_LONG = "Der Markt schließt gleich. Beehren sie uns doch " +
054 "morgen wieder.";
055 public static final String MARKET_CLOSES_NOT = "Der Markt hat doch noch eine Weile geöffnet.";
056 public static final String MARKET_CLOSED = "Der Markt hat geschlossen.";
057 public static final String MARKET_OPENED = "Der Markt hat geöffnet.";
058 private static final String SHOP_CAPTION = "Großmarkt Sohn & Sohn";
059
060 private MenuSheetItem msiNewCustomer;
061 private MenuSheetItem msiCustomer;
062 private MenuSheetItem msiSeller;
063 private MenuSheetItem msiWorker;
064 private MenuSheetItem msiManager;
065 private Calendar dateOfOpening;
066
067
068 /**
069 * The {@link Options options}, which affect the computation of the discount and the
070 * dismissal compensation.
071 */
072 private Options options = new Options();
073
074 /**
075 * The listeners listening to market events.
076 */
077 private MarketEventListener[] evl = new MarketEventListener [0];
078
079 /**
080 * Indicates if market ist open, soon to close, or closed.
081 */
082 private int open;
083
084 /**
085 * Indicates if the market's time has advanced.
086 * This variable is set to true when the day changes. As soon as the market opens,
087 * timeAdvanced will be false.<br>
088 * That makes it possible to distinguish between the two possibilities
089 * <ol><li>time has advanced and market can be opened</li>
090 * <li>market has just closed and day has not been changed yet</li></ol>
091 */
092 private boolean timeAdvanced;
093
094 /**
095 * Catalog which contains all {@link CIArticle CIArticles}
096 */
097 private CatalogImpl c_articleCatalog;
098
099 /**
100 * Stock which contains all {@link CIArticle CIArticles} currently available
101 */
102 private CSOffer cs_offer;
103
104 /**
105 * Catalog which contains all orders placed by the manager that have not yet arrived.
106 */
107 private COpenPurchaseOrders c_openPurchaseOrders;
108
109 /**
110 * Catalog that stores all customers' names.
111 * This catalog is needed for the customer stock ({@link #ss_tillQueue till queue}).
112 */
113 private CatalogImpl c_customer;
114
115 /**
116 * Catalog that stores sales statistics for the current day. This Catalog is used to make sure that
117 * sales don't show up in the statistics unless the day-end closing has been completed.
118 */
119 private CSalesStats c_dailyStats;
120
121 /**
122 * Catalog that stores sales statistics (amount of sold articles, revenue from sold articles...)
123 * for one month.
124 */
125 private CSalesStats c_monthlyStats;
126
127 /**
128 * Catalog that stores {@link CSalesStats sales statistics} of all passed months.
129 */
130 private CCompleteStats c_completeStats;
131
132 /**
133 * Catalog that stores the statistics of all market's customers. Those statistics are
134 * time independend, that means, it is not split up into months.
135 */
136 private CCustomerStats c_customerStats;
137
138 /**
139 * The global queue of customers' orders waiting for warehouse-worker-processing.
140 */
141 private StoringStockImpl ss_warehouseQueue;
142
143 /**
144 * The global queue of customers waiting at the till.
145 */
146 private StoringStockImpl ss_tillQueue;
147
148 /**
149 * The money of the market.
150 */
151 private IntegerValue iv_account;
152
153
154 //####################### SalesPoint methods ################################################################
155
156 /**
157 * Creates an SMarket, initiates global Catalogs, Stocks and other settings.
158 */
159 public SMarket(Time time){
160 super();
161 setTheShop(this);
162 setTimer(new StepTimer(time));
163 setShopFrameBounds(new Rectangle(50,50,400,300));
164 setShopFrameTitle(SHOP_CAPTION + " - " + getTime());
165 IconSetter.setIcon(getShopFrame());
166 open = 2; timeAdvanced = true; //shop starts in the morning
167 c_articleCatalog = new CArticleCatalog(CAT_ARTICLECATALOG);
168 addCatalog(c_articleCatalog);
169 cs_offer = new CSOffer(STK_OFFER, c_articleCatalog);
170 addStock(cs_offer);
171 c_customer = new CatalogImpl(CAT_CUSTOMER);
172 addCatalog(c_customer);
173 ss_tillQueue = new SSListenable(STK_TILLQUEUE, c_customer);
174 addStock(ss_tillQueue);
175 ss_warehouseQueue = new SSListenable(STK_WAREHOUSEQUEUE, c_customer);
176 addStock(ss_warehouseQueue);
177 iv_account = new IntegerValue(0);
178 //clone, otherwise dateOfOpening would change with current time
179 dateOfOpening = (Calendar)getTime().clone();
180 }
181
182 /**
183 * Returns the JFrame of the Shop window. The difference to the {@link Shop Shop's} getShopFrame()
184 * method is, that this one is public, as the Shop's window is needed by a dialog.
185 * @see JDDShowMessage#showMessageDialog(String, String)
186 *
187 * @return the Shop's frame.
188 */
189 public JFrame getShopFrame() {
190 return super.getShopFrame();
191 }
192
193 /**
194 * Starts the Shop and initializes statistics items.
195 */
196 public void start() {
197 c_openPurchaseOrders = new COpenPurchaseOrders(CAT_OPENPURCHASE);
198 addCatalog(c_openPurchaseOrders);
199 c_monthlyStats = new CSalesStats(getYear(), getMonth());
200 c_monthlyStats.initPriceHistory();
201 addCatalog(c_monthlyStats);
202 c_dailyStats = new CSalesStats(getYear(), getMonth());
203 c_customerStats = new CCustomerStats();
204 c_completeStats = new CCompleteStats(CAT_COMPLETE_SALESSTATS);
205 addCatalog(c_completeStats);
206 super.start();
207 try {
208 Log.setGlobalLogFile("marketlog.txt", true, false);
209 }
210 catch (IOException e) {
211 System.err.println("Cannot set log file");
212 }
213 setOpen(0);
214 }
215
216 /**
217 * Closes the SMarket.
218 */
219 public void quit() {
220 if (shutdown (false)) {
221 System.exit(0);
222 }
223 }
224
225 /**
226 * Sets the icon when market is loaded from persistence file.
227 */
228 public void resume() {
229 super.resume();
230 IconSetter.setIcon(getShopFrame());
231 }
232
233 /**
234 * Creates the MenuSheet of the SMarket
235 *
236 * @return the MenuSheet of the SMarket
237 */
238 public MenuSheet createShopMenuSheet(){
239 MenuSheet msMenuBar = new MenuSheet("Menubar");
240 MenuSheet msShop = (MenuSheet)super.createShopMenuSheet().getTaggedItem(Shop.SHOP_MENU_TAG, false);
241 MenuSheet msLogOn = new MenuSheet("Anmeldung");
242 MenuSheet msSimulation = new MenuSheet("Simulation");
243 msiNewCustomer = new MenuSheetItem("Kundenregistrierung", SProcessCustomerEditProfile.create());
244 msiCustomer = new MenuSheetItem("Kunde", SProcessLogOn.createLogOnProcess(UMUserBase.CUSTOMER));
245 msiSeller = new MenuSheetItem("Kasse", SProcessLogOn.createLogOnProcess(UMUserBase.SELLER));
246 msiWorker = new MenuSheetItem("Lager", SProcessLogOn.createLogOnProcess(UMUserBase.WAREHOUSE_WORKER));
247 msiManager = new MenuSheetItem("Manager", SProcessLogOn.createLogOnProcess(UMUserBase.MANAGER));
248 MenuSheetItem msiAdvanceTime = new MenuSheetItem("Zu Wunschdatum vor", new Action() {
249 private static final long serialVersionUID = -6709968809343202422L;
250 public void doAction(SaleProcess p, SalesPoint sp) {
251 if (isOpen()) {
252 JDDShowMessage.showMessageDialog(
253 "Die Zeit kann erst weitergeschaltet werden,\nwenn der Markt " +
254 "geschlossen ist.\n\n (Manager -> System -> Öffnen/Schließen)", "Fehler");
255 } else {
256 SMarket.getTheShop().addSalesPoint(new SPTime());
257 }
258 }
259 });
260 msLogOn.add(msiNewCustomer);
261 msLogOn.add(msiCustomer);
262 msLogOn.add(msiSeller);
263 msLogOn.add(msiWorker);
264 msLogOn.add(msiManager);
265 msSimulation.add(msiAdvanceTime);
266 msMenuBar.add(msShop);
267 msMenuBar.add(msLogOn);
268 msMenuBar.add(msSimulation);
269 return msMenuBar;
270 }
271
272 /**
273 * Adds a {@link SalesPoint} to the market attaches a {@link MarketEventListener} to it.
274 *
275 * @param sp the SalesPoint to be added.
276 */
277 public void addSalesPoint(SalesPoint sp) {
278 super.addSalesPoint(sp);
279 if (sp instanceof SPListenable) SMarket.addEventListener((SPListenable)sp);
280 if (sp instanceof SPCustomer) SMarket.addEventListener((SPCustomer)sp);
281 }
282
283 /**
284 * Removes a {@link SalesPoint} to the market detachses its {@link MarketEventListener}.
285 *
286 * @param sp the SalesPoint to be removed.
287 */
288 public void removeSalesPoint(SalesPoint sp) {
289 super.removeSalesPoint(sp);
290 if (sp instanceof SPListenable) SMarket.removeEventListener((SPListenable)sp);
291 if (sp instanceof SPCustomer) SMarket.removeEventListener((SPCustomer)sp);
292 }
293
294
295
296 //##################### Our methods #########################################################################
297
298 ////////////////////////////////////////////////////////////////////////////////////////////////////////
299 // Account (getting and setting)
300 ////////////////////////////////////////////////////////////////////////////////////////////////////////
301
302 /**
303 * Adds a Value to the markets account.
304 *
305 * @param money the Value that will be added.
306 */
307 public static void addToAccount(Value money) {
308 ((SMarket)Shop.getTheShop()).iv_account.addAccumulating(money);
309 }
310
311 /**
312 * Subtracts a Value from the markets account.
313 *
314 * @param money the Value that will be substracted.
315 */
316 public static void subtractFromAccount(Value money) {
317 ((SMarket)Shop.getTheShop()).iv_account.subtractAccumulating(money);
318 }
319
320 /**
321 * @return the account of the market as Value.
322 */
323 public static Value getAccount(){
324 return ((SMarket)Shop.getTheShop()).iv_account;
325 }
326
327 public static Options getOptions() {
328 return getTheMarket().options;
329 }
330
331
332 ////////////////////////////////////////////////////////////////////////////////
333 // Shortcuts
334 ////////////////////////////////////////////////////////////////////////////////
335
336 /**
337 * @return the singleton instance of SMarket.
338 */
339 public static SMarket getTheMarket() {
340 return (SMarket)getTheShop();
341 }
342
343 /**
344 * Shortcut for catalog with all articles.
345 */
346 public static CArticleCatalog getArticleCatalog() {
347 return (CArticleCatalog)getTheShop().getCatalog(CAT_ARTICLECATALOG);
348 }
349
350 /**
351 * Shortcut to the market's current stock.
352 */
353 public static CSOffer getOffer() {
354 return (CSOffer)getTheShop().getStock(STK_OFFER);
355 }
356
357 /**
358 * Shortcut to the catalog that holds the market's purchases which have not yet arrived.
359 */
360 public static COpenPurchaseOrders getOpenPurchaseOrder() {
361 return (COpenPurchaseOrders)getTheShop().getCatalog(CAT_OPENPURCHASE);
362 }
363
364 /**
365 * Shortcut to the catalog that holds all customers of the market.
366 * This catalog is needed as a base for till- and warehouse-queue.
367 */
368 public static Catalog getCustomers(){
369 return Shop.getTheShop().getCatalog(SMarket.CAT_CUSTOMER);
370 }
371
372 /**
373 * Shortcut for the queue of customers who want to pay.
374 */
375 public static SSListenable getTillQueue(){
376 return (SSListenable)Shop.getTheShop().getStock(SMarket.STK_TILLQUEUE);
377 }
378
379 /**
380 * Shortcut for the queue of orders waiting at the warehouse.
381 */
382 public static SSListenable getWarehouseQueue(){
383 return (SSListenable)Shop.getTheShop().getStock(SMarket.STK_WAREHOUSEQUEUE);
384 }
385
386 /**
387 * Shortcut to the catalog that holds the current day's statistics.
388 */
389 public static CSalesStats getDailySalesStats() {
390 return (CSalesStats)(getTheMarket()).c_dailyStats;
391 }
392
393 /**
394 * Shortcut to the catalog that holds the current month's statistics.
395 */
396 public static CSalesStats getMonthlySalesStats() {
397 return (CSalesStats)(getTheMarket()).c_monthlyStats;
398 }
399
400 /**
401 * Shortcut to the statistics catalog
402 */
403 public static CCompleteStats getCompleteSalesStats() {
404 return (CCompleteStats)getTheShop().getCatalog(CAT_COMPLETE_SALESSTATS);
405 }
406
407 /**
408 * Shortcut to the customer stats catalog
409 */
410 public static CCustomerStats getCustomerStats() {
411 return getTheMarket().c_customerStats;
412 }
413
414 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
415 // Misc.
416 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
417
418 /**
419 * Returns Categories of all available Articles.
420 * This method is used by dropdown filters for initialization.
421 */
422 public static Object[] getArticleCategories(){
423 List<String> l = new ArrayList<String>();
424 l.add("Alles");
425 Iterator it = getArticleCatalog().iterator(null, false);
426 CIArticle art = null;
427 String category = null;
428 while (it.hasNext()) {
429 art = (CIArticle)it.next();
430 category = art.getCategory();
431 if (!l.contains(category)) {
432 l.add(category);
433 }
434 }
435 return l.toArray();
436 }
437
438 /**
439 * Sets the market's state.
440 *
441 * @param i <ul>
442 * <li>0: The market is open, customers can buy</li>
443 * <li>1: The market is about to close, customers cannot login nor start new
444 * purchases, even if they are already logged in.</li>
445 * <li>2: The market is closed, only the manager can log in</li>
446 * </ul>
447 */
448 public void setOpen(int i) {
449 open = i;
450 if (i == 0) {
451 timeAdvanced = false;
452 msiNewCustomer.setEnabled(true);
453 msiCustomer.setEnabled(true);
454 msiSeller.setEnabled(true);
455 msiWorker.setEnabled(true);
456 }
457 if (i == 1) {
458 fireMarketClosing();
459 msiNewCustomer.setEnabled(false);
460 msiCustomer.setEnabled(false);
461 }
462 if (i == 2) {
463 fireMarketClosed();
464 addDailyStatsToMonthlyStats();
465 msiNewCustomer.setEnabled(false);
466 msiCustomer.setEnabled(false);
467 msiSeller.setEnabled(false);
468 msiWorker.setEnabled(false);
469 }
470 }
471
472 /**
473 * @return whether the market is currently open or not.
474 */
475 public static boolean isOpen() {
476 return getTheMarket().open == 0 || getTheMarket().open == 1;
477 }
478
479 /**
480 * @return whether the manager has announced the market's closing or not.
481 */
482 public static boolean isToBeClosed() {
483 return getTheMarket().open == 1;
484 }
485
486 /**
487 * @return whether the time has advanced or not.
488 * @see #timeAdvanced
489 */
490 public static boolean hasTimeAdvanced() {
491 return getTheMarket().timeAdvanced;
492 }
493
494
495 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
496 // Time
497 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
498
499 /**
500 * Convenience method
501 *
502 * @return the current date.
503 */
504 public static Calendar getTime() {
505 return (Calendar)getTheMarket().getTimer().getTime();
506 }
507
508 /**
509 * @return the date that the market has started its business.
510 */
511 public static Calendar getDateOfOpening() {
512 return getTheMarket().dateOfOpening;
513 }
514
515 /**
516 * Convencience method.
517 *
518 * @return the current year.
519 */
520 public static int getYear() {
521 return getTime().get(Calendar.YEAR);
522 }
523
524 /**
525 * Convenience method.
526 *
527 * @return the current month.
528 */
529 public static int getMonth() {
530 return getTime().get(Calendar.MONTH);
531 }
532
533 /**
534 * Sets the market's time to a new date.
535 *
536 * @param newTime the new date to be set.
537 */
538 public static void setTime(Calendar newTime) {
539 int diff = Conversions.dayDifference(getTime(), newTime);
540 getTheShop().getTimer().setTime(newTime);
541 getTheMarket().computeEventsOnDayChanges(diff);
542 }
543
544 /**
545 * Advances the market's time by 1 day.
546 */
547 public static void setNextDay() {
548 getTheShop().getTimer().goAhead();
549 getTheMarket().computeEventsOnDayChanges(1);
550 }
551
552 /**
553 * Does things that need to be done when the time advances.
554 * The Shop's title is set to the new date, the waiting time for new orders is decreased,
555 * if new orders arrived they are added to the current offer.
556 * If not only the day but also the month changed, the statistics and the market's account
557 * are updated.
558 *
559 * @param daysAdvanced The number of days the time advanced.
560 */
561 private void computeEventsOnDayChanges(int daysAdvanced) {
562 setShopFrameTitle(SHOP_CAPTION + " - " + getTime());
563 timeAdvanced = true;
564 //when open purchase orders arrive, add them to market's stock, otherwise just decrease the
565 //numbers of days to wait
566 CountingStock arrivedOrders = getOpenPurchaseOrder().subtractPassedDays(daysAdvanced);
567 if(arrivedOrders.size(null)>0){
568 getOffer().addStock(arrivedOrders, null, false);
569 getWarehouseQueue().fireWakeUpOrders();
570 }
571 if (hasMonthChanged(daysAdvanced)) {//if month changed
572 getMonthlySalesStats().setWages(
573 UMUserBase.getGlobalBase().getCurrentWages()); //save current wages to statistics
574 getCompleteSalesStats().add(getMonthlySalesStats(), null); //update statistics catalogs
575 int currentMiscCosts = c_monthlyStats.getCosts();
576 considerJumpedOverMonths();
577 c_monthlyStats = new CSalesStats(getYear(), getMonth());
578 c_monthlyStats.setCosts(currentMiscCosts);
579 c_monthlyStats.initPriceHistory();
580 subtractFromAccount(new IntegerValue(monthlyCosts())); //update account
581 }
582 fireTimeAdvanced();
583 }
584
585 /**
586 * This method checks if the month changed due to the progress of time.
587 *
588 * @param daysAdvanced The number of days the time advanced.
589 * @return true, if the month changed
590 */
591 private boolean hasMonthChanged(int daysAdvanced) {
592 int dayOfMonth = getTime().get(Calendar.DAY_OF_MONTH);
593 return daysAdvanced >= dayOfMonth;
594 }
595
596 /**
597 * Adds an empty statistics entry to the statistics for every month that has been jumped over.
598 * Besides, the monthly costs of the market are subtracted from the account.
599 */
600 private void considerJumpedOverMonths() {
601 int currentMiscCosts = c_monthlyStats.getCosts();
602 CCompleteStats ccs = getCompleteSalesStats();
603 int m = Statistics.getLastArticleStatisticsMonth() + 1; //set not to last month, but to its successor
604 int y = Statistics.getLastArticleStatisticsYear();
605 if (m == 12) {
606 m = 0;
607 y++;
608 }
609 int mNow = getMonth();
610 int yNow = getYear();
611 while (m != mNow || y != yNow) {
612 CSalesStats css = new CSalesStats(y, m);
613 css.setCosts(currentMiscCosts);
614 css.initPriceHistory();
615 css.setWages(UMUserBase.getGlobalBase().getCurrentWages());
616 ccs.add(css, null);
617 subtractFromAccount(new IntegerValue(monthlyCosts())); //update account
618 m++;
619 if (m == 12) {
620 m = 0;
621 y++;
622 }
623 }
624 }
625
626 /**
627 * Adds today's statistic entries to the monthly stats.
628 * This covers the sales statistics of every single article and the current day's total revenue.
629 */
630 private void addDailyStatsToMonthlyStats() {
631 Iterator it = c_dailyStats.iterator(null, false);
632 while (it.hasNext()) {
633 CISalesStats dailyCiss = (CISalesStats)it.next();
634 c_monthlyStats.get(dailyCiss.getArticleID()).addAmount(dailyCiss.getAmount());
635 c_monthlyStats.get(dailyCiss.getArticleID()).addRevenue(dailyCiss.getRevenue());
636 }
637 c_monthlyStats.addRevenue(c_dailyStats.getRevenue());
638 c_dailyStats = new CSalesStats(getYear(), getMonth());
639 }
640
641 /**
642 * Convenience method that returns the total costs per month.
643 * This covers both the whole wages and the miscellaneous costs that were set in the options.
644 */
645 private int monthlyCosts() {
646 return UMUserBase.getGlobalBase().getCurrentWages() + c_monthlyStats.getCosts();
647 }
648
649
650 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
651 // Event handling
652 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
653
654 /**
655 * Adds a new EventListener to the market.
656 */
657 public static void addEventListener(MarketEventListener e) {
658 MarketEventListener[] evl = (getTheMarket()).evl;
659 int len = evl.length;
660 boolean exists = false;
661 for (int i = 0; i < len; i++) {
662 exists = exists || (evl[i] == e);
663 }
664 if (!exists) {
665 MarketEventListener[] temp = new MarketEventListener[len+1];
666 System.arraycopy(evl, 0, temp, 0, len);
667 temp[len] = e;
668 evl = temp;
669 }
670 (getTheMarket()).evl = evl;
671 }
672
673 /**
674 * Removes an EventListener from the market.
675 */
676 public static void removeEventListener(MarketEventListener e) {
677 MarketEventListener[] evl = (getTheMarket()).evl;
678 for (int i = 0; i < evl.length; i++) {
679 if (evl[i] == e) {
680 MarketEventListener[] temp = new MarketEventListener[evl.length-1];
681 if (i > 0) System.arraycopy(evl,0,temp,0,i);
682 if (i < evl.length-1) System.arraycopy(evl,i+1,temp,i,evl.length-1-i);
683 evl = temp;
684 break;
685 }
686 }
687 (getTheMarket()).evl = evl;
688 }
689
690
691 /**
692 * Fires an event to all listeners: The market is about to close. (Which means, the manager pressed
693 * his "Closing-Time" button.)
694 */
695 public static void fireMarketClosing() {
696 MarketEventListener[] evl = (getTheMarket()).evl;
697 for (int i = 0; i < evl.length; i++) {
698 if (evl[i] != null) evl[i].notifyOnMarketClosing();
699 }
700 }
701
702 /**
703 * Fires an event to all listeners: The market isn't about to close anymore. (Which means, the manager
704 * canceled closing time.)
705 */
706 public static void fireMarketNotClosing() {
707 MarketEventListener[] evl = (getTheMarket()).evl;
708 for (int i = 0; i < evl.length; i++) {
709 if (evl[i] != null) evl[i].notifyOnMarketNotClosing();
710 }
711 }
712
713 /**
714 * Fires an event to all listeners: The market has just closed.
715 */
716 public static void fireMarketClosed() {
717 MarketEventListener[] evl = (getTheMarket()).evl;
718 for (int i = 0; i < evl.length; i++) {
719 if (evl[i] != null) evl[i].marketClosed();
720 }
721 }
722
723 /**
724 * Fires an event to all listeners: The market has just opened.
725 */
726 public static void fireMarketOpened() {
727 MarketEventListener[] evl = (getTheMarket()).evl;
728 for (int i = 0; i < evl.length; i++) {
729 if (evl[i] != null) evl[i].marketOpened();
730 }
731 }
732
733 /**
734 * Fires an event to all listeners: The time has advanced..
735 */
736 public static void fireTimeAdvanced() {
737 MarketEventListener[] evl = (getTheMarket()).evl;
738 for (int i = 0; i < evl.length; i++) {
739 if (evl[i] != null) evl[i].timeAdvanced();
740 }
741 }
742
743 /**
744 * Fires an event to all listeners: The number of workers or orders to process has changed.
745 */
746 public static void fireUpdateWorkerScreen(){
747 MarketEventListener[] evl = (getTheMarket()).evl;
748 for (int i = 0; i < evl.length; i++) {
749 if (evl[i] != null) evl[i].workerInformationChanged();
750 }
751 }
752 }