graph_gui.c
changeset 1086 adbaa5bda683
parent 1085 56facccb1f3d
child 1093 4fdc46eaf423
equal deleted inserted replaced
1085:56facccb1f3d 1086:adbaa5bda683
   332 		gd.color_2 = 0xD7;
   332 		gd.color_2 = 0xD7;
   333 		gd.bg_line_color = 0xE;
   333 		gd.bg_line_color = 0xE;
   334 
   334 
   335 		SetupGraphDrawerForPlayers(&gd);
   335 		SetupGraphDrawerForPlayers(&gd);
   336 
   336 
   337 		numd = -1;
   337 		numd = 0;
   338 		FOR_ALL_PLAYERS(p) {
   338 		FOR_ALL_PLAYERS(p) {
       
   339 			if (p->is_active) {
       
   340 				gd.colors[numd] = _color_list[p->player_color].window_color_bgb;
       
   341 				for(j=gd.num_on_x_axis,i=0; --j >= 0;) {
       
   342 					gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)(p->old_economy[j].income + p->old_economy[j].expenses);
       
   343 					i++;
       
   344 				}
       
   345 			}
   339 			numd++;
   346 			numd++;
   340 			if (!p->is_active)
   347 		}
   341 				continue;
   348 
   342 			gd.colors[numd] = _color_list[p->player_color].window_color_bgb;
   349 		gd.num_dataset = numd;
   343 			for(j=gd.num_on_x_axis,i=0; --j >= 0;) {
       
   344 				gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)(p->old_economy[j].income + p->old_economy[j].expenses);
       
   345 				i++;
       
   346 			}
       
   347 		}
       
   348 
       
   349 		gd.num_dataset = numd + 1;
       
   350 
   350 
   351 		DrawGraph(&gd);
   351 		DrawGraph(&gd);
   352 	}	break;
   352 	}	break;
   353 	case WE_CLICK:
   353 	case WE_CLICK:
   354 		if (e->click.widget == 2) /* Clicked on Legend */
   354 		if (e->click.widget == 2) /* Clicked on Legend */
   405 		gd.color_3 = 0x10;
   405 		gd.color_3 = 0x10;
   406 		gd.color_2 = 0xD7;
   406 		gd.color_2 = 0xD7;
   407 		gd.bg_line_color = 0xE;
   407 		gd.bg_line_color = 0xE;
   408 		SetupGraphDrawerForPlayers(&gd);
   408 		SetupGraphDrawerForPlayers(&gd);
   409 
   409 
   410 		numd = -1;
   410 		numd = 0;
   411 		FOR_ALL_PLAYERS(p) {
   411 		FOR_ALL_PLAYERS(p) {
       
   412 			if (p->is_active) {
       
   413 				gd.colors[numd] = _color_list[p->player_color].window_color_bgb;
       
   414 				for(j=gd.num_on_x_axis,i=0; --j >= 0;) {
       
   415 					gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)p->old_economy[j].income;
       
   416 					i++;
       
   417 				}
       
   418 			}
   412 			numd++;
   419 			numd++;
   413 			if (!p->is_active)
   420 		}
   414 				continue;
   421 
   415 			gd.colors[numd] = _color_list[p->player_color].window_color_bgb;
   422 		gd.num_dataset = numd;
   416 			for(j=gd.num_on_x_axis,i=0; --j >= 0;) {
       
   417 				gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)p->old_economy[j].income;
       
   418 				i++;
       
   419 			}
       
   420 		}
       
   421 
       
   422 		gd.num_dataset = numd + 1;
       
   423 
   423 
   424 		DrawGraph(&gd);
   424 		DrawGraph(&gd);
   425 		break;
   425 		break;
   426 	}
   426 	}
   427 
   427 
   478 		gd.color_3 = 0x10;
   478 		gd.color_3 = 0x10;
   479 		gd.color_2 = 0xD7;
   479 		gd.color_2 = 0xD7;
   480 		gd.bg_line_color = 0xE;
   480 		gd.bg_line_color = 0xE;
   481 		SetupGraphDrawerForPlayers(&gd);
   481 		SetupGraphDrawerForPlayers(&gd);
   482 
   482 
   483 		numd = -1;
   483 		numd = 0;
   484 		FOR_ALL_PLAYERS(p) {
   484 		FOR_ALL_PLAYERS(p) {
       
   485 			if (p->is_active) {
       
   486 				gd.colors[numd] = _color_list[p->player_color].window_color_bgb;
       
   487 				for(j=gd.num_on_x_axis,i=0; --j >= 0;) {
       
   488 					gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)p->old_economy[j].delivered_cargo;
       
   489 					i++;
       
   490 				}
       
   491 			}
   485 			numd++;
   492 			numd++;
   486 			if (!p->is_active)
   493 		}
   487 				continue;
   494 
   488 			gd.colors[numd] = _color_list[p->player_color].window_color_bgb;
   495 		gd.num_dataset = numd;
   489 			for(j=gd.num_on_x_axis,i=0; --j >= 0;) {
       
   490 				gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)p->old_economy[j].delivered_cargo;
       
   491 				i++;
       
   492 			}
       
   493 		}
       
   494 
       
   495 		gd.num_dataset = numd + 1;
       
   496 
   496 
   497 		DrawGraph(&gd);
   497 		DrawGraph(&gd);
   498 		break;
   498 		break;
   499 	}
   499 	}
   500 
   500 
   524 void ShowDeliveredCargoGraph()
   524 void ShowDeliveredCargoGraph()
   525 {
   525 {
   526 	if (AllocateWindowDescFront(&_delivered_cargo_graph_desc, 0)) {
   526 	if (AllocateWindowDescFront(&_delivered_cargo_graph_desc, 0)) {
   527 		InvalidateWindow(WC_GRAPH_LEGEND, 0);
   527 		InvalidateWindow(WC_GRAPH_LEGEND, 0);
   528 	}
   528 	}
       
   529 }
       
   530 
       
   531 /***********************/
       
   532 /* PERFORMANCE HISTORY */
       
   533 /***********************/
       
   534 
       
   535 static void PerformanceHistoryWndProc(Window *w, WindowEvent *e)
       
   536 {
       
   537 	switch(e->event) {
       
   538 	case WE_PAINT: {
       
   539 		GraphDrawer gd;
       
   540 		Player *p;
       
   541 		int i,j;
       
   542 		int numd;
       
   543 
       
   544 		DrawWindowWidgets(w);
       
   545 
       
   546 		gd.left = 2;
       
   547 		gd.top = 18;
       
   548 		gd.height = 200;
       
   549 		gd.include_neg = false;
       
   550 		gd.format_str_y_axis = STR_7024;
       
   551 		gd.color_3 = 0x10;
       
   552 		gd.color_2 = 0xD7;
       
   553 		gd.bg_line_color = 0xE;
       
   554 		SetupGraphDrawerForPlayers(&gd);
       
   555 
       
   556 		numd = 0;
       
   557 		FOR_ALL_PLAYERS(p) {
       
   558 			if (p->is_active) {
       
   559 				gd.colors[numd] = _color_list[p->player_color].window_color_bgb;
       
   560 				for(j=gd.num_on_x_axis,i=0; --j >= 0;) {
       
   561 					gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)p->old_economy[j].performance_history;
       
   562 					i++;
       
   563 				}
       
   564 			}
       
   565 			numd++;
       
   566 		}
       
   567 
       
   568 		gd.num_dataset = numd;
       
   569 
       
   570 		DrawGraph(&gd);
       
   571 		break;
       
   572 	}
       
   573 
       
   574 	case WE_CLICK:
       
   575 		if (e->click.widget == 2)
       
   576 			ShowGraphLegend();
       
   577 		if (e->click.widget == 3)
       
   578 			ShowPerformanceRatingDetail();
       
   579 		break;
       
   580 	}
       
   581 }
       
   582 
       
   583 static const Widget _performance_history_widgets[] = {
       
   584 {    WWT_TEXTBTN,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,															STR_018B_CLOSE_WINDOW},
       
   585 {    WWT_CAPTION,   RESIZE_NONE,    14,    11,   475,     0,    13, STR_7051_COMPANY_PERFORMANCE_RATINGS,	STR_018C_WINDOW_TITLE_DRAG_THIS},
       
   586 { WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   526,   575,     0,    13, STR_704C_KEY,													STR_704D_SHOW_KEY_TO_GRAPHS},
       
   587 { WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   476,   525,     0,    13, STR_PERFORMANCE_DETAIL_KEY,						STR_704D_SHOW_KEY_TO_GRAPHS},
       
   588 {     WWT_IMGBTN,   RESIZE_NONE,    14,     0,   575,    14,   237, 0x0,																		STR_NULL},
       
   589 {   WIDGETS_END},
       
   590 };
       
   591 
       
   592 static const WindowDesc _performance_history_desc = {
       
   593 	-1, -1, 576, 238,
       
   594 	WC_PERFORMANCE_HISTORY,0,
       
   595 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
       
   596 	_performance_history_widgets,
       
   597 	PerformanceHistoryWndProc
       
   598 };
       
   599 
       
   600 void ShowPerformanceHistoryGraph()
       
   601 {
       
   602 	if (AllocateWindowDescFront(&_performance_history_desc, 0)) {
       
   603 		InvalidateWindow(WC_GRAPH_LEGEND, 0);
       
   604 	}
       
   605 }
       
   606 
       
   607 /*****************/
       
   608 /* COMPANY VALUE */
       
   609 /*****************/
       
   610 
       
   611 static void CompanyValueGraphWndProc(Window *w, WindowEvent *e)
       
   612 {
       
   613 	switch(e->event) {
       
   614 	case WE_PAINT: {
       
   615 		GraphDrawer gd;
       
   616 		Player *p;
       
   617 		int i,j;
       
   618 		int numd;
       
   619 
       
   620 		DrawWindowWidgets(w);
       
   621 
       
   622 		gd.left = 2;
       
   623 		gd.top = 18;
       
   624 		gd.height = 200;
       
   625 		gd.include_neg = false;
       
   626 		gd.format_str_y_axis = STR_CURRCOMPACT64;
       
   627 		gd.color_3 = 0x10;
       
   628 		gd.color_2 = 0xD7;
       
   629 		gd.bg_line_color = 0xE;
       
   630 		SetupGraphDrawerForPlayers(&gd);
       
   631 
       
   632 		numd = 0;
       
   633 		FOR_ALL_PLAYERS(p) {
       
   634 			if (p->is_active) {
       
   635 				gd.colors[numd] = _color_list[p->player_color].window_color_bgb;
       
   636 				for(j=gd.num_on_x_axis,i=0; --j >= 0;) {
       
   637 					gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)p->old_economy[j].company_value;
       
   638 					i++;
       
   639 				}
       
   640 			}
       
   641 			numd++;
       
   642 		}
       
   643 
       
   644 		gd.num_dataset = numd;
       
   645 
       
   646 		DrawGraph(&gd);
       
   647 		break;
       
   648 	}
       
   649 
       
   650 	case WE_CLICK:
       
   651 		if (e->click.widget == 2)
       
   652 			ShowGraphLegend();
       
   653 		break;
       
   654 	}
       
   655 }
       
   656 
       
   657 static const Widget _company_value_graph_widgets[] = {
       
   658 {    WWT_TEXTBTN,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,								STR_018B_CLOSE_WINDOW},
       
   659 {    WWT_CAPTION,   RESIZE_NONE,    14,    11,   525,     0,    13, STR_7052_COMPANY_VALUES,	STR_018C_WINDOW_TITLE_DRAG_THIS},
       
   660 { WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   526,   575,     0,    13, STR_704C_KEY,						STR_704D_SHOW_KEY_TO_GRAPHS},
       
   661 {     WWT_IMGBTN,   RESIZE_NONE,    14,     0,   575,    14,   237, 0x0,											STR_NULL},
       
   662 {   WIDGETS_END},
       
   663 };
       
   664 
       
   665 static const WindowDesc _company_value_graph_desc = {
       
   666 	-1, -1, 576, 238,
       
   667 	WC_COMPANY_VALUE,0,
       
   668 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
       
   669 	_company_value_graph_widgets,
       
   670 	CompanyValueGraphWndProc
       
   671 };
       
   672 
       
   673 void ShowCompanyValueGraph()
       
   674 {
       
   675 	if (AllocateWindowDescFront(&_company_value_graph_desc, 0)) {
       
   676 		InvalidateWindow(WC_GRAPH_LEGEND, 0);
       
   677 	}
       
   678 }
       
   679 
       
   680 /*****************/
       
   681 /* PAYMENT RATES */
       
   682 /*****************/
       
   683 
       
   684 static const byte _cargo_legend_colors[12] = {152, 32, 15, 174, 208, 194, 191, 84, 184, 10, 202, 215};
       
   685 
       
   686 static void CargoPaymentRatesWndProc(Window *w, WindowEvent *e)
       
   687 {
       
   688 	switch(e->event) {
       
   689 	case WE_PAINT: {
       
   690 		int i, j, x, y;
       
   691 		GraphDrawer gd;
       
   692 
       
   693 		gd.sel = _legend_cargobits;
       
   694 		w->click_state = (~_legend_cargobits) << 3;
       
   695 		DrawWindowWidgets(w);
       
   696 
       
   697 		x = 495;
       
   698 		y = 25;
       
   699 
       
   700 		for(i=0; i!=NUM_CARGO; i++) {
       
   701 			GfxFillRect(x, y, x+8, y+5, 0);
       
   702 			GfxFillRect(x+1, y+1, x+7, y+4, _cargo_legend_colors[i]);
       
   703 			SetDParam(0, _cargoc.names_s[i]);
       
   704 			DrawString(x+14, y, STR_7065, 0);
       
   705 			y += 8;
       
   706 		}
       
   707 
       
   708 		gd.left = 2;
       
   709 		gd.top = 24;
       
   710 		gd.height = 104;
       
   711 		gd.include_neg = false;
       
   712 		gd.format_str_y_axis = STR_CURRCOMPACT32;
       
   713 		gd.color_3 = 16;
       
   714 		gd.color_2 = 215;
       
   715 		gd.bg_line_color = 14;
       
   716 		gd.num_dataset = NUM_CARGO;
       
   717 		gd.num_on_x_axis = 20;
       
   718 		gd.num_vert_lines = 20;
       
   719 		gd.month = 0xFF;
       
   720 		gd.unk61A = 10;
       
   721 		gd.unk61C = 10;
       
   722 
       
   723 		for(i=0; i!=NUM_CARGO; i++) {
       
   724 			gd.colors[i] = _cargo_legend_colors[i];
       
   725 			for(j=0; j!=20; j++) {
       
   726 				gd.cost[i][j] = (uint64)GetTransportedGoodsIncome(10, 20, j*6+6,i);
       
   727 			}
       
   728 		}
       
   729 
       
   730 		DrawGraph(&gd);
       
   731 
       
   732 		DrawString(2 + 46, 24 + gd.height + 7, STR_7062_DAYS_IN_TRANSIT, 0);
       
   733 		DrawString(2 + 84, 24 - 9, STR_7063_PAYMENT_FOR_DELIVERING, 0);
       
   734 	} break;
       
   735 
       
   736 	case WE_CLICK: {
       
   737 		switch(e->click.widget) {
       
   738 		case 3: case 4: case 5: case 6:
       
   739 		case 7: case 8: case 9: case 10:
       
   740 		case 11: case 12: case 13: case 14:
       
   741 			_legend_cargobits ^= 1 << (e->click.widget - 3);
       
   742 			SetWindowDirty(w);
       
   743 			break;
       
   744 		}
       
   745 	} break;
       
   746 	}
       
   747 }
       
   748 
       
   749 static const Widget _cargo_payment_rates_widgets[] = {
       
   750 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,											STR_018B_CLOSE_WINDOW},
       
   751 {    WWT_CAPTION,   RESIZE_NONE,    14,    11,   567,     0,    13, STR_7061_CARGO_PAYMENT_RATES,	STR_018C_WINDOW_TITLE_DRAG_THIS},
       
   752 {      WWT_PANEL,   RESIZE_NONE,    14,     0,   567,    14,   141, 0x0,														STR_NULL},
       
   753 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    24,    31, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   754 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    32,    39, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   755 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    40,    47, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   756 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    48,    55, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   757 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    56,    63, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   758 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    64,    71, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   759 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    72,    79, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   760 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    80,    87, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   761 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    88,    95, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   762 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    96,   103, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   763 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,   104,   111, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   764 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,   112,   119, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   765 {   WIDGETS_END},
       
   766 };
       
   767 
       
   768 static const WindowDesc _cargo_payment_rates_desc = {
       
   769 	-1, -1, 568, 142,
       
   770 	WC_PAYMENT_RATES,0,
       
   771 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
       
   772 	_cargo_payment_rates_widgets,
       
   773 	CargoPaymentRatesWndProc
       
   774 };
       
   775 
       
   776 
       
   777 void ShowCargoPaymentRates()
       
   778 {
       
   779 	AllocateWindowDescFront(&_cargo_payment_rates_desc, 0);
       
   780 }
       
   781 
       
   782 /************************/
       
   783 /* COMPANY LEAGUE TABLE */
       
   784 /************************/
       
   785 
       
   786 static const StringID _performance_titles[] = {
       
   787 	STR_7066_ENGINEER,
       
   788 	STR_7066_ENGINEER,
       
   789 	STR_7067_TRAFFIC_MANAGER,
       
   790 	STR_7067_TRAFFIC_MANAGER,
       
   791 	STR_7068_TRANSPORT_COORDINATOR,
       
   792 	STR_7068_TRANSPORT_COORDINATOR,
       
   793 	STR_7069_ROUTE_SUPERVISOR,
       
   794 	STR_7069_ROUTE_SUPERVISOR,
       
   795 	STR_706A_DIRECTOR,
       
   796 	STR_706A_DIRECTOR,
       
   797 	STR_706B_CHIEF_EXECUTIVE,
       
   798 	STR_706B_CHIEF_EXECUTIVE,
       
   799 	STR_706C_CHAIRMAN,
       
   800 	STR_706C_CHAIRMAN,
       
   801 	STR_706D_PRESIDENT,
       
   802 	STR_706E_TYCOON,
       
   803 };
       
   804 
       
   805 static inline StringID GetPerformanceTitleFromValue(uint value)
       
   806 {
       
   807 	return _performance_titles[minu(value, 1000) >> 6];
       
   808 }
       
   809 
       
   810 static int CDECL _perf_hist_comp(const void *elem1, const void *elem2 ) {
       
   811 	const Player *p1 = *(const Player* const *)elem1;
       
   812 	const Player *p2 = *(const Player* const *)elem2;
       
   813 	int32 v = p2->old_economy[1].performance_history - p1->old_economy[1].performance_history;
       
   814 	return (v!=0) | (v >> (sizeof(int32)*8-1));
       
   815 }
       
   816 
       
   817 static void CompanyLeagueWndProc(Window *w, WindowEvent *e)
       
   818 {
       
   819 	switch(e->event) {
       
   820 	case WE_PAINT: {
       
   821 		Player *p;
       
   822 		Player *plist[MAX_PLAYERS];
       
   823 		size_t pl_num, i;
       
   824 
       
   825 		DrawWindowWidgets(w);
       
   826 
       
   827 		pl_num=0;
       
   828 		FOR_ALL_PLAYERS(p) {
       
   829 			if (p->is_active)
       
   830 				plist[pl_num++] = p;
       
   831 		}
       
   832 		assert(pl_num > 0);
       
   833 
       
   834 		qsort(plist, pl_num, sizeof(Player*), _perf_hist_comp);
       
   835 
       
   836 		i = 0;
       
   837 		do {
       
   838 			SetDParam(0, i + 1 + STR_01AB);
       
   839 			p = plist[i];
       
   840 			SetDParam(1, p->name_1);
       
   841 			SetDParam(2, p->name_2);
       
   842 
       
   843 			SetDParam(3, GetPlayerNameString(p->index, 4));
       
   844 			/*	WARNING ugly hack!
       
   845 					GetPlayerNameString sets up (Player #) if the player is human in an extra DPARAM16
       
   846 					It seems that if player is non-human, nothing is set up, so param is 0. GetString doesn't like
       
   847 					that because there is another param after it.
       
   848 					So we'll just shift the rating one back if player is AI and all is fine
       
   849 				*/
       
   850 			SetDParam((IS_HUMAN_PLAYER(p->index) ? 5 : 4), GetPerformanceTitleFromValue(p->old_economy[1].performance_history));
       
   851 
       
   852 			DrawString(2, 15 + i * 10, i == 0 ? STR_7054 : STR_7055, 0);
       
   853 			DrawPlayerIcon(p->index, 27, 16 + i * 10);
       
   854 		} while (++i != pl_num);
       
   855 
       
   856 		break;
       
   857 	}
       
   858 	}
       
   859 }
       
   860 
       
   861 
       
   862 static const Widget _company_league_widgets[] = {
       
   863 {    WWT_TEXTBTN,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,											STR_018B_CLOSE_WINDOW},
       
   864 {    WWT_CAPTION,   RESIZE_NONE,    14,    11,   399,     0,    13, STR_7053_COMPANY_LEAGUE_TABLE,	STR_018C_WINDOW_TITLE_DRAG_THIS},
       
   865 {     WWT_IMGBTN,   RESIZE_NONE,    14,     0,   399,    14,    96, 0x0,														STR_NULL},
       
   866 {   WIDGETS_END},
       
   867 };
       
   868 
       
   869 static const WindowDesc _company_league_desc = {
       
   870 	-1, -1, 400, 97,
       
   871 	WC_COMPANY_LEAGUE,0,
       
   872 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
       
   873 	_company_league_widgets,
       
   874 	CompanyLeagueWndProc
       
   875 };
       
   876 
       
   877 void ShowCompanyLeagueTable()
       
   878 {
       
   879 	AllocateWindowDescFront(&_company_league_desc,0);
   529 }
   880 }
   530 
   881 
   531 /*****************************/
   882 /*****************************/
   532 /* PERFORMANCE RATING DETAIL */
   883 /* PERFORMANCE RATING DETAIL */
   533 /*****************************/
   884 /*****************************/
   745 
  1096 
   746 void ShowPerformanceRatingDetail()
  1097 void ShowPerformanceRatingDetail()
   747 {
  1098 {
   748 	AllocateWindowDescFront(&_performance_rating_detail_desc, 0);
  1099 	AllocateWindowDescFront(&_performance_rating_detail_desc, 0);
   749 }
  1100 }
   750 
       
   751 /***********************/
       
   752 /* PERFORMANCE HISTORY */
       
   753 /***********************/
       
   754 
       
   755 static void PerformanceHistoryWndProc(Window *w, WindowEvent *e)
       
   756 {
       
   757 	switch(e->event) {
       
   758 	case WE_PAINT: {
       
   759 		GraphDrawer gd;
       
   760 		Player *p;
       
   761 		int i,j;
       
   762 		int numd;
       
   763 
       
   764 		DrawWindowWidgets(w);
       
   765 
       
   766 		gd.left = 2;
       
   767 		gd.top = 18;
       
   768 		gd.height = 200;
       
   769 		gd.include_neg = false;
       
   770 		gd.format_str_y_axis = STR_7024;
       
   771 		gd.color_3 = 0x10;
       
   772 		gd.color_2 = 0xD7;
       
   773 		gd.bg_line_color = 0xE;
       
   774 		SetupGraphDrawerForPlayers(&gd);
       
   775 
       
   776 		numd = -1;
       
   777 		FOR_ALL_PLAYERS(p) {
       
   778 			numd++;
       
   779 			if (!p->is_active)
       
   780 				continue;
       
   781 			gd.colors[numd] = _color_list[p->player_color].window_color_bgb;
       
   782 			for(j=gd.num_on_x_axis,i=0; --j >= 0;) {
       
   783 				gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)p->old_economy[j].performance_history;
       
   784 				i++;
       
   785 			}
       
   786 		}
       
   787 
       
   788 		gd.num_dataset = numd + 1;
       
   789 
       
   790 		DrawGraph(&gd);
       
   791 		break;
       
   792 	}
       
   793 
       
   794 	case WE_CLICK:
       
   795 		if (e->click.widget == 2)
       
   796 			ShowGraphLegend();
       
   797 		if (e->click.widget == 3)
       
   798 			ShowPerformanceRatingDetail();
       
   799 		break;
       
   800 	}
       
   801 }
       
   802 
       
   803 static const Widget _performance_history_widgets[] = {
       
   804 {    WWT_TEXTBTN,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,															STR_018B_CLOSE_WINDOW},
       
   805 {    WWT_CAPTION,   RESIZE_NONE,    14,    11,   475,     0,    13, STR_7051_COMPANY_PERFORMANCE_RATINGS,	STR_018C_WINDOW_TITLE_DRAG_THIS},
       
   806 { WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   526,   575,     0,    13, STR_704C_KEY,													STR_704D_SHOW_KEY_TO_GRAPHS},
       
   807 { WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   476,   525,     0,    13, STR_PERFORMANCE_DETAIL_KEY,						STR_704D_SHOW_KEY_TO_GRAPHS},
       
   808 {     WWT_IMGBTN,   RESIZE_NONE,    14,     0,   575,    14,   237, 0x0,																		STR_NULL},
       
   809 {   WIDGETS_END},
       
   810 };
       
   811 
       
   812 static const WindowDesc _performance_history_desc = {
       
   813 	-1, -1, 576, 238,
       
   814 	WC_PERFORMANCE_HISTORY,0,
       
   815 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
       
   816 	_performance_history_widgets,
       
   817 	PerformanceHistoryWndProc
       
   818 };
       
   819 
       
   820 void ShowPerformanceHistoryGraph()
       
   821 {
       
   822 	if (AllocateWindowDescFront(&_performance_history_desc, 0)) {
       
   823 		InvalidateWindow(WC_GRAPH_LEGEND, 0);
       
   824 	}
       
   825 }
       
   826 
       
   827 /*****************/
       
   828 /* COMPANY VALUE */
       
   829 /*****************/
       
   830 
       
   831 static void CompanyValueGraphWndProc(Window *w, WindowEvent *e)
       
   832 {
       
   833 	switch(e->event) {
       
   834 	case WE_PAINT: {
       
   835 		GraphDrawer gd;
       
   836 		Player *p;
       
   837 		int i,j;
       
   838 		int numd;
       
   839 
       
   840 		DrawWindowWidgets(w);
       
   841 
       
   842 		gd.left = 2;
       
   843 		gd.top = 18;
       
   844 		gd.height = 200;
       
   845 		gd.include_neg = false;
       
   846 		gd.format_str_y_axis = STR_CURRCOMPACT64;
       
   847 		gd.color_3 = 0x10;
       
   848 		gd.color_2 = 0xD7;
       
   849 		gd.bg_line_color = 0xE;
       
   850 		SetupGraphDrawerForPlayers(&gd);
       
   851 
       
   852 		numd = -1;
       
   853 		FOR_ALL_PLAYERS(p) {
       
   854 			numd++;
       
   855 			if (!p->is_active)
       
   856 				continue;
       
   857 
       
   858 			gd.colors[numd] = _color_list[p->player_color].window_color_bgb;
       
   859 			for(j=gd.num_on_x_axis,i=0; --j >= 0;) {
       
   860 				gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_VALUE : (uint64)p->old_economy[j].company_value;
       
   861 				i++;
       
   862 			}
       
   863 		}
       
   864 
       
   865 		gd.num_dataset = numd + 1;
       
   866 
       
   867 		DrawGraph(&gd);
       
   868 		break;
       
   869 	}
       
   870 
       
   871 	case WE_CLICK:
       
   872 		if (e->click.widget == 2)
       
   873 			ShowGraphLegend();
       
   874 		break;
       
   875 	}
       
   876 }
       
   877 
       
   878 static const Widget _company_value_graph_widgets[] = {
       
   879 {    WWT_TEXTBTN,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,								STR_018B_CLOSE_WINDOW},
       
   880 {    WWT_CAPTION,   RESIZE_NONE,    14,    11,   525,     0,    13, STR_7052_COMPANY_VALUES,	STR_018C_WINDOW_TITLE_DRAG_THIS},
       
   881 { WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   526,   575,     0,    13, STR_704C_KEY,						STR_704D_SHOW_KEY_TO_GRAPHS},
       
   882 {     WWT_IMGBTN,   RESIZE_NONE,    14,     0,   575,    14,   237, 0x0,											STR_NULL},
       
   883 {   WIDGETS_END},
       
   884 };
       
   885 
       
   886 static const WindowDesc _company_value_graph_desc = {
       
   887 	-1, -1, 576, 238,
       
   888 	WC_COMPANY_VALUE,0,
       
   889 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
       
   890 	_company_value_graph_widgets,
       
   891 	CompanyValueGraphWndProc
       
   892 };
       
   893 
       
   894 void ShowCompanyValueGraph()
       
   895 {
       
   896 	if (AllocateWindowDescFront(&_company_value_graph_desc, 0)) {
       
   897 		InvalidateWindow(WC_GRAPH_LEGEND, 0);
       
   898 	}
       
   899 }
       
   900 
       
   901 /*****************/
       
   902 /* PAYMENT RATES */
       
   903 /*****************/
       
   904 
       
   905 static const byte _cargo_legend_colors[12] = {152, 32, 15, 174, 208, 194, 191, 84, 184, 10, 202, 215};
       
   906 
       
   907 static void CargoPaymentRatesWndProc(Window *w, WindowEvent *e)
       
   908 {
       
   909 	switch(e->event) {
       
   910 	case WE_PAINT: {
       
   911 		int i, j, x, y;
       
   912 		GraphDrawer gd;
       
   913 
       
   914 		gd.sel = _legend_cargobits;
       
   915 		w->click_state = (~_legend_cargobits) << 3;
       
   916 		DrawWindowWidgets(w);
       
   917 
       
   918 		x = 495;
       
   919 		y = 25;
       
   920 
       
   921 		for(i=0; i!=NUM_CARGO; i++) {
       
   922 			GfxFillRect(x, y, x+8, y+5, 0);
       
   923 			GfxFillRect(x+1, y+1, x+7, y+4, _cargo_legend_colors[i]);
       
   924 			SetDParam(0, _cargoc.names_s[i]);
       
   925 			DrawString(x+14, y, STR_7065, 0);
       
   926 			y += 8;
       
   927 		}
       
   928 
       
   929 		gd.left = 2;
       
   930 		gd.top = 24;
       
   931 		gd.height = 104;
       
   932 		gd.include_neg = false;
       
   933 		gd.format_str_y_axis = STR_CURRCOMPACT32;
       
   934 		gd.color_3 = 16;
       
   935 		gd.color_2 = 215;
       
   936 		gd.bg_line_color = 14;
       
   937 		gd.num_dataset = 12;
       
   938 		gd.num_on_x_axis = 20;
       
   939 		gd.num_vert_lines = 20;
       
   940 		gd.month = 0xFF;
       
   941 		gd.unk61A = 10;
       
   942 		gd.unk61C = 10;
       
   943 
       
   944 		for(i=0; i!=NUM_CARGO; i++) {
       
   945 			gd.colors[i] = _cargo_legend_colors[i];
       
   946 			for(j=0; j!=20; j++) {
       
   947 				gd.cost[i][j] = (uint64)GetTransportedGoodsIncome(10, 20, j*6+6,i);
       
   948 			}
       
   949 		}
       
   950 
       
   951 		DrawGraph(&gd);
       
   952 
       
   953 		DrawString(2 + 46, 24 + gd.height + 7, STR_7062_DAYS_IN_TRANSIT, 0);
       
   954 		DrawString(2 + 84, 24 - 9, STR_7063_PAYMENT_FOR_DELIVERING, 0);
       
   955 	} break;
       
   956 
       
   957 	case WE_CLICK: {
       
   958 		switch(e->click.widget) {
       
   959 		case 3: case 4: case 5: case 6:
       
   960 		case 7: case 8: case 9: case 10:
       
   961 		case 11: case 12: case 13: case 14:
       
   962 			_legend_cargobits ^= 1 << (e->click.widget - 3);
       
   963 			SetWindowDirty(w);
       
   964 			break;
       
   965 		}
       
   966 	} break;
       
   967 	}
       
   968 }
       
   969 
       
   970 static const Widget _cargo_payment_rates_widgets[] = {
       
   971 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,											STR_018B_CLOSE_WINDOW},
       
   972 {    WWT_CAPTION,   RESIZE_NONE,    14,    11,   567,     0,    13, STR_7061_CARGO_PAYMENT_RATES,	STR_018C_WINDOW_TITLE_DRAG_THIS},
       
   973 {      WWT_PANEL,   RESIZE_NONE,    14,     0,   567,    14,   141, 0x0,														STR_NULL},
       
   974 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    24,    31, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   975 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    32,    39, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   976 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    40,    47, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   977 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    48,    55, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   978 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    56,    63, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   979 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    64,    71, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   980 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    72,    79, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   981 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    80,    87, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   982 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    88,    95, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   983 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    96,   103, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   984 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,   104,   111, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   985 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,   112,   119, 0x0,														STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   986 {   WIDGETS_END},
       
   987 };
       
   988 
       
   989 static const WindowDesc _cargo_payment_rates_desc = {
       
   990 	-1, -1, 568, 142,
       
   991 	WC_PAYMENT_RATES,0,
       
   992 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
       
   993 	_cargo_payment_rates_widgets,
       
   994 	CargoPaymentRatesWndProc
       
   995 };
       
   996 
       
   997 
       
   998 void ShowCargoPaymentRates()
       
   999 {
       
  1000 	AllocateWindowDescFront(&_cargo_payment_rates_desc, 0);
       
  1001 }
       
  1002 
       
  1003 /************************/
       
  1004 /* COMPANY LEAGUE TABLE */
       
  1005 /************************/
       
  1006 
       
  1007 static const StringID _performance_titles[] = {
       
  1008 	STR_7066_ENGINEER,
       
  1009 	STR_7066_ENGINEER,
       
  1010 	STR_7067_TRAFFIC_MANAGER,
       
  1011 	STR_7067_TRAFFIC_MANAGER,
       
  1012 	STR_7068_TRANSPORT_COORDINATOR,
       
  1013 	STR_7068_TRANSPORT_COORDINATOR,
       
  1014 	STR_7069_ROUTE_SUPERVISOR,
       
  1015 	STR_7069_ROUTE_SUPERVISOR,
       
  1016 	STR_706A_DIRECTOR,
       
  1017 	STR_706A_DIRECTOR,
       
  1018 	STR_706B_CHIEF_EXECUTIVE,
       
  1019 	STR_706B_CHIEF_EXECUTIVE,
       
  1020 	STR_706C_CHAIRMAN,
       
  1021 	STR_706C_CHAIRMAN,
       
  1022 	STR_706D_PRESIDENT,
       
  1023 	STR_706E_TYCOON,
       
  1024 };
       
  1025 
       
  1026 static inline StringID GetPerformanceTitleFromValue(uint value)
       
  1027 {
       
  1028 	return _performance_titles[minu(value, 1000) >> 6];
       
  1029 }
       
  1030 
       
  1031 static int CDECL _perf_hist_comp(const void *elem1, const void *elem2 ) {
       
  1032 	const Player *p1 = *(const Player* const *)elem1;
       
  1033 	const Player *p2 = *(const Player* const *)elem2;
       
  1034 	int32 v = p2->old_economy[1].performance_history - p1->old_economy[1].performance_history;
       
  1035 	return (v!=0) | (v >> (sizeof(int32)*8-1));
       
  1036 }
       
  1037 
       
  1038 static void CompanyLeagueWndProc(Window *w, WindowEvent *e)
       
  1039 {
       
  1040 	switch(e->event) {
       
  1041 	case WE_PAINT: {
       
  1042 		Player *p;
       
  1043 		Player *plist[MAX_PLAYERS];
       
  1044 		size_t pl_num, i;
       
  1045 
       
  1046 		DrawWindowWidgets(w);
       
  1047 
       
  1048 		pl_num=0;
       
  1049 		FOR_ALL_PLAYERS(p) {
       
  1050 			if (p->is_active)
       
  1051 				plist[pl_num++] = p;
       
  1052 		}
       
  1053 		assert(pl_num > 0);
       
  1054 
       
  1055 		qsort(plist, pl_num, sizeof(Player*), _perf_hist_comp);
       
  1056 
       
  1057 		i = 0;
       
  1058 		do {
       
  1059 			SetDParam(0, i + 1 + STR_01AB);
       
  1060 			p = plist[i];
       
  1061 			SetDParam(1, p->name_1);
       
  1062 			SetDParam(2, p->name_2);
       
  1063 
       
  1064 			SetDParam(3, GetPlayerNameString(p->index, 4));
       
  1065 			/*	WARNING ugly hack!
       
  1066 					GetPlayerNameString sets up (Player #) if the player is human in an extra DPARAM16
       
  1067 					It seems that if player is non-human, nothing is set up, so param is 0. GetString doesn't like
       
  1068 					that because there is another param after it.
       
  1069 					So we'll just shift the rating one back if player is AI and all is fine
       
  1070 				*/
       
  1071 			SetDParam((IS_HUMAN_PLAYER(p->index) ? 5 : 4), GetPerformanceTitleFromValue(p->old_economy[1].performance_history));
       
  1072 
       
  1073 			DrawString(2, 15 + i * 10, i == 0 ? STR_7054 : STR_7055, 0);
       
  1074 			DrawPlayerIcon(p->index, 27, 16 + i * 10);
       
  1075 		} while (++i != pl_num);
       
  1076 
       
  1077 		break;
       
  1078 	}
       
  1079 	}
       
  1080 }
       
  1081 
       
  1082 
       
  1083 static const Widget _company_league_widgets[] = {
       
  1084 {    WWT_TEXTBTN,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,											STR_018B_CLOSE_WINDOW},
       
  1085 {    WWT_CAPTION,   RESIZE_NONE,    14,    11,   399,     0,    13, STR_7053_COMPANY_LEAGUE_TABLE,	STR_018C_WINDOW_TITLE_DRAG_THIS},
       
  1086 {     WWT_IMGBTN,   RESIZE_NONE,    14,     0,   399,    14,    96, 0x0,														STR_NULL},
       
  1087 {   WIDGETS_END},
       
  1088 };
       
  1089 
       
  1090 static const WindowDesc _company_league_desc = {
       
  1091 	-1, -1, 400, 97,
       
  1092 	WC_COMPANY_LEAGUE,0,
       
  1093 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
       
  1094 	_company_league_widgets,
       
  1095 	CompanyLeagueWndProc
       
  1096 };
       
  1097 
       
  1098 void ShowCompanyLeagueTable()
       
  1099 {
       
  1100 	AllocateWindowDescFront(&_company_league_desc,0);
       
  1101 }