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