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 }