OSDN Git Service

45d627a38e95d932719b6b35c158d761dc767411
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / View / AntiAirPanel.cs
1 // Copyright (C) 2016 Kazuhiro Fujieda <fujieda@users.osdn.me>\r
2 //\r
3 // Licensed under the Apache License, Version 2.0 (the "License");\r
4 // you may not use this file except in compliance with the License.\r
5 // You may obtain a copy of the License at\r
6 //\r
7 //    http://www.apache.org/licenses/LICENSE-2.0\r
8 //\r
9 // Unless required by applicable law or agreed to in writing, software\r
10 // distributed under the License is distributed on an "AS IS" BASIS,\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
12 // See the License for the specific language governing permissions and\r
13 // limitations under the License.\r
14 \r
15 using System.Collections.Generic;\r
16 using System.Drawing;\r
17 using System.Linq;\r
18 using System.Windows.Forms;\r
19 using KancolleSniffer.Model;\r
20 \r
21 namespace KancolleSniffer.View\r
22 {\r
23     public class AntiAirPanel : Panel\r
24     {\r
25         private const int LineHeight = 16;\r
26         private readonly List<AntiAirLabels> _labelList = new List<AntiAirLabels>();\r
27         private readonly List<Record> _table = new List<Record>();\r
28 \r
29         private class AntiAirLabels : ShipLabels\r
30         {\r
31             public Label Rate { get; set; }\r
32             public Label Diff { get; set; }\r
33 \r
34             public override Control[] AddedControls => new Control[] {Rate, Diff};\r
35         }\r
36 \r
37         public void Update(Sniffer sniffer)\r
38         {\r
39             CreateTable(sniffer);\r
40             SuspendLayout();\r
41             CreateLabels();\r
42             SetRecords();\r
43             ResumeLayout();\r
44         }\r
45 \r
46         private class Record\r
47         {\r
48             public string Fleet { get; set; }\r
49             public string Ship { get; set; }\r
50             public int Id { get; set; }\r
51             public string Rate { get; set; }\r
52             public string Diff { get; set; }\r
53 \r
54             public Record()\r
55             {\r
56                 Fleet = Ship = Rate = Diff = "";\r
57             }\r
58         }\r
59 \r
60         private void CreateTable(Sniffer sniffer)\r
61         {\r
62             _table.Clear();\r
63             var fn = new[] {"第一艦隊", "第二艦隊", "第三艦隊", "第四艦隊"};\r
64             foreach (var fleet in sniffer.Fleets)\r
65             {\r
66                 var ships = fleet.ActualShips;\r
67                 var rawForFleet = ships.Sum(ship => ship.EffectiveAntiAirForFleet);\r
68                 var forFleet = new[] {1.0, 1.2, 1.6}.Select(r => (int)(rawForFleet * r) * 2 / 1.3).ToArray();\r
69                 _table.Add(new Record\r
70                 {\r
71                     Fleet = fn[fleet.Number] + " 防空" + string.Join("/", forFleet.Select(x => x.ToString("f1")))\r
72                 });\r
73                 foreach (var ship in ships)\r
74                 {\r
75                     _table.Add(CreateShipRecord(ship));\r
76                     _table.Add(CreateAntiAirRecord(forFleet, ship));\r
77                 }\r
78             }\r
79         }\r
80 \r
81         private Record CreateShipRecord(ShipStatus ship)\r
82         {\r
83             var param = " Lv" + ship.Level +\r
84                         " 加重" + ship.EffectiveAntiAirForShip.ToString("d") +\r
85                         AntiAirPropellantBarrageChance(ship);\r
86             var name = ship.Name;\r
87             var realWidth = Scaler.ScaleWidth(ListForm.PanelWidth - 10);\r
88             return new Record\r
89             {\r
90                 Ship = StringTruncator.Truncate(name, param, realWidth, GetFont(name)) + param,\r
91                 Id = ship.Id\r
92             };\r
93         }\r
94 \r
95         private Record CreateAntiAirRecord(double[] forFleet, ShipStatus ship)\r
96         {\r
97             var rate = ship.EffectiveAntiAirForShip / 4.0;\r
98             var diff = forFleet.Select(x => (x + ship.EffectiveAntiAirForShip) / 10.0);\r
99             return new Record\r
100             {\r
101                 Rate = "割合" + rate.ToString("f1") + "% ",\r
102                 Diff = "固定" + string.Join("/", diff.Select(d => d.ToString("f1")))\r
103             };\r
104         }\r
105 \r
106         private static Font GetFont(string name)\r
107         {\r
108             return ShipLabel.Name.StartWithLetter(name)\r
109                 ? ShipLabel.Name.LatinFont\r
110                 : ShipLabel.Name.BaseFont;\r
111         }\r
112 \r
113         private static string AntiAirPropellantBarrageChance(ShipStatus ship)\r
114         {\r
115             // ReSharper disable once CompareOfFloatsByEqualityOperator\r
116             if (ship.AntiAirPropellantBarrageChance == 0)\r
117                 return "";\r
118             var chance = ship.AntiAirPropellantBarrageChance;\r
119             return " 弾幕" + (chance < 100 ? chance.ToString("f1") : ((int)chance).ToString());\r
120         }\r
121 \r
122         private void CreateLabels()\r
123         {\r
124             for (var i = _labelList.Count; i < _table.Count; i++)\r
125                 CreateLabels(i);\r
126         }\r
127 \r
128         private void CreateLabels(int i)\r
129         {\r
130             var y = 1 + LineHeight * i;\r
131             var labels = new AntiAirLabels\r
132             {\r
133                 Fleet = new ShipLabel.Fleet(new Point(1, 3)),\r
134                 Name = new ShipLabel.Name(new Point(10, 3), ShipNameWidth.Max),\r
135                 Rate = new Label {Location = new Point(35, 3), AutoSize = true},\r
136                 Diff = new Label {Location = new Point(100, 3), AutoSize = true},\r
137                 BackPanel = new Panel\r
138                 {\r
139                     Location = new Point(0, y),\r
140                     Size = new Size(ListForm.PanelWidth, LineHeight)\r
141                 }\r
142             };\r
143             _labelList.Add(labels);\r
144             labels.Arrange(this, CustomColors.ColumnColors.BrightFirst(i));\r
145             labels.Move(AutoScrollPosition);\r
146         }\r
147 \r
148         private void SetRecords()\r
149         {\r
150             for (var i = 0; i < _table.Count; i++)\r
151                 SetRecord(i);\r
152             for (var i = _table.Count; i < _labelList.Count; i++)\r
153                 _labelList[i].BackPanel.Visible = false;\r
154         }\r
155 \r
156         private void SetRecord(int i)\r
157         {\r
158             var lbp = _labelList[i].BackPanel;\r
159             var column = _table[i];\r
160             var labels = _labelList[i];\r
161             labels.Fleet.Text = column.Fleet;\r
162             labels.Name.SetName(column.Ship);\r
163             labels.Rate.Text = column.Rate;\r
164             labels.Diff.Text = column.Diff;\r
165             lbp.Visible = true;\r
166         }\r
167 \r
168         public void ShowShip(int id)\r
169         {\r
170             var i = _table.FindIndex(e => e.Id == id);\r
171             if (i == -1)\r
172                 return;\r
173             var y = Scaler.ScaleHeight(LineHeight * i);\r
174             AutoScrollPosition = new Point(0, y);\r
175         }\r
176     }\r
177 }