-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathResourceCollection.cs
More file actions
243 lines (221 loc) · 10.6 KB
/
Copy pathResourceCollection.cs
File metadata and controls
243 lines (221 loc) · 10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/*
* Idmr.LfdReader.dll, Library file to read and write LFD resource files
* Copyright (C) 2009-2021 Michael Gaisser (mjgaisser@gmail.com)
* Licensed under the MPL v2.0 or later
*
* Full notice in help/Idmr.LfdReader.chm
* Version: 2.0
*/
/* CHANGE LOG
* v2.0, 210309
* [UPD] cleanup
* v1.1, 141215
* [UPD] changed license to MPL
* v1.0
*/
using System;
using System.Collections.Generic;
namespace Idmr.LfdReader
{
/// <summary>Collection object for the resources in an <see cref="LfdFile"/>.</summary>
public class ResourceCollection : IEnumerable<Resource>
{
List<Resource> _items = null;
readonly string _lockedMessage = "Collection structure is currently locked (";
#region constructors
/// <summary>Creates a new empty Collection.</summary>
/// <remarks>Structure is unlocked, <see cref="Add()"/>, <see cref="Insert(int)"/> and <see cref="RemoveAt"/> can be used.</remarks>
public ResourceCollection()
{
CanEditStructure = true;
}
/// <summary>Creates a new Collection with multiple initial Resource placeholders.</summary>
/// <param name="quantity">Number of Resources to start with.</param>
/// <remarks>Structure is locked.</remarks>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="quantity"/> is not positive.</exception>
public ResourceCollection(int quantity)
{
if (quantity > 0) _items = new List<Resource>(quantity);
else throw new ArgumentOutOfRangeException("quantity", "quantity must be positive");
for (int i = 0; i < quantity; i++) _items.Add(new Resource());
}
/// <summary>Creates a new Collection with the specified structure.</summary>
/// <param name="category">Structure of file to initialize.</param>
/// <remarks>Using <see cref="LfdFile.LfdCategory.Normal"/> is the same as using the blank constructor, otherwise structure is locked.<br/>
/// Battle Delt palette is defined by EMPIRE.PLTTstandard and TOURDESK.PLTTtoddesk.</remarks>
public ResourceCollection(LfdFile.LfdCategory category)
{
if (category == LfdFile.LfdCategory.Battle)
{
_items = new List<Resource>(2)
{
new Text(),
new Delt()
};
_items[0].Name = "battle#";
_items[1].Name = "b#gal";
}
else if (category == LfdFile.LfdCategory.Cockpit)
{
_items = new List<Resource>(3)
{
new Panl(true),
new Mask(),
new Pltt()
};
}
else CanEditStructure = true;
}
#endregion constructors
#region public methods
/// <summary>Finds the resource with the specified <see cref="Resource.Tag"/> value.</summary>
/// <param name="tag">User-defined data.</param>
/// <returns>The first matching Resource, otherwise <see langword="null"/>.</returns>
public Resource GetResourceByTag(object tag)
{
for (int i = 0; i < Count; i++)
if (_items[i].Tag != null && _items[i].Tag.ToString() == tag.ToString()) return _items[i];
return null;
}
/// <summary>Finds the index of the resource with the specified <see cref="Resource.Tag"/> value.</summary>
/// <param name="tag">User-defined data.</param>
/// <returns>The index of the first matching Resource, otherwise <b>-1</b>.</returns>
public int GetIndexByTag(object tag)
{
for (int i = 0; i < Count; i++)
if (_items[i].Tag != null && _items[i].Tag.ToString() == tag.ToString()) return i;
return -1;
}
/// <summary>Finds the resource with the specified <see cref="Resource.Tag"/> value and replaces it with <paramref name="resource"/>.</summary>
/// <param name="tag">The value to search for.</param>
/// <param name="resource">The new Resource.</param>
/// <remarks>If <paramref name="tag"/> is not found, no action is taken.</remarks>
/// <exception cref="InvalidOperationException">Attempted to call when structure is locked and <see cref="Resource.Type"/> or <see cref="Resource.Name"/> have been changed.</exception>
public void SetByTag(object tag, Resource resource)
{
for (int i = 0; i < Count; i++)
if (_items[i].Tag.ToString() == tag.ToString())
{
if (!CanEditStructure && (_items[i].Name != resource.Name || _items[i].Type != resource.Type))
throw new InvalidOperationException(_lockedMessage + "SetByTag)");
_items[i] = resource;
_items[i].Tag = tag;
break;
}
}
/// <summary>Empties the Collection of entries.</summary>
/// <remarks>All existing resources are lost, <see cref="Count"/> will be <b>zero</b>.</remarks>
/// <exception cref="InvalidOperationException">Attempted to call when structure is locked.</exception>
public void Clear()
{
if (!CanEditStructure) throw new InvalidOperationException(_lockedMessage + "Clear)");
_items.Clear();
}
/// <summary>Adds a new Resource to the end of the Collection.</summary>
/// <exception cref="InvalidOperationException">Attempted to call when structure is locked.</exception>
public void Add() { add(new Resource()); }
/// <summary>Adds the given Resource to the end of the Collection.</summary>
/// <param name="resource">The Resource to be added.</param>
/// <exception cref="InvalidOperationException">Attempted to call when structure is locked.</exception>
public void Add(Resource resource) { add(resource); }
/// <summary>Inserts a new Resource at the specified index.</summary>
/// <param name="index">Location of the Resource within the Collection.</param>
/// <exception cref="ArgumentOutOfRangeException">Invalid <paramref name="index"/> value.</exception>
/// <exception cref="InvalidOperationException">Attempted to call when structure is locked.</exception>
public void Insert(int index) { insert(index, new Resource()); }
/// <summary>Inserts the given Resource at the specified index.</summary>
/// <param name="index">Location of the Resource.</param>
/// <param name="resource">The Resource to be added.</param>
/// <exception cref="ArgumentOutOfRangeException">Invalid <paramref name="index"/> value.</exception>
/// <exception cref="InvalidOperationException">Attempted to call when structure is locked.</exception>
public void Insert(int index, Resource resource) { insert(index, resource); }
/// <summary>Deletes the Resource at the specified index.</summary>
/// <param name="index">The index of the Resource to be deleted.</param>
/// <exception cref="ArgumentOutOfRangeException">Invalid <paramref name="index"/> value.</exception>
/// <exception cref="InvalidOperationException">Attempted to call when structure is locked<br/><b>-or-</b><br/>Collection is empty.</exception>
public void RemoveAt(int index) { removeAt(index); }
#endregion public methods
#region public properties
/// <summary>A single Resource within the collection.</summary>
/// <param name="index">The location within the collection.</param>
/// <exception cref="IndexOutOfRangeException">Invalid <paramref name="index"/> value.</exception>
/// <exception cref="InvalidOperationException">Attempted to set when structure is locked and <see cref="Resource.Type"/> or <see cref="Resource.Name"/> have been changed.</exception>
public Resource this[int index]
{
get { return _items[index]; }
set
{
if (!CanEditStructure && _items[index].Type != Resource.ResourceType.Undefined && (_items[index].Name != value.Name || _items[index].Type != value.Type))
throw new InvalidOperationException(_lockedMessage + "Item)");
_items[index] = value;
}
}
/// <summary>A single Resource within the collection.</summary>
/// <param name="label">The identifying string of the Resource in the form of "<see cref="Type">TYPE</see><see cref="Resource.Name"/>".</param>
/// <exception cref="ArgumentException">Resource not found.</exception>
/// <exception cref="InvalidOperationException">Attempted to set when structure is locked and <see cref="Resource.Type"/> or <see cref="Resource.Name"/> have been changed.</exception>
/// <returns>The Resource matching <paramref name="label"/>, otherwise <see langword="null"/>.</returns>
/// <remarks><paramref name="label"/> is the same format as <see cref="Resource.ToString()"/>.</remarks>
public Resource this[string label]
{
get
{
for (int i = 0; i < Count; i++)
if (_items[i].ToString() == label) return _items[i];
return null;
}
set
{
int index = -1;
for (int i = 0; i < Count; i++)
if (_items[i].ToString() == label) { index = i; break; }
if (index == -1) throw new ArgumentException("label not found");
if (!CanEditStructure && _items[index].Type != Resource.ResourceType.Undefined && (_items[index].Name != value.Name || _items[index].Type != value.Type))
throw new InvalidOperationException(_lockedMessage + "Item)");
_items[index] = value;
}
}
/// <summary>Gets the number of objects in the Collection.</summary>
/// <remarks>If internal List is <see langword="null"/>, returns <b>-1</b>.</remarks>
public int Count { get { return (_items == null ? -1 : _items.Count); } }
/// <summary>Gets or sets whether or not the structure is unlocked.</summary>
/// <remarks>Default is <see langword="false"/>, set to <see langword="true"/> when initialized with <see cref="ResourceCollection()"/> or <see cref="LfdFile.LfdCategory.Normal"/>.<br/>
/// When locked, <see cref="Resource.Type"/> and <see cref="Resource.Name"/> are read-only, Collection cannot be resized.</remarks>
public bool CanEditStructure { get; set; }
#endregion public properties
void add(Resource item)
{
if (!CanEditStructure) throw new InvalidOperationException(_lockedMessage + "add)");
if (_items == null) _items = new List<Resource>(1);
_items.Add(item);
}
void insert(int index, Resource item)
{
if (!CanEditStructure) throw new InvalidOperationException(_lockedMessage + "insert)");
if (_items == null) _items = new List<Resource>(1);
if (index >= 0 && index <= Count) _items.Insert(index, item);
else throw new ArgumentOutOfRangeException("index", "Invalid index value, (0-" + Count + ")");
}
void removeAt(int index)
{
if (!CanEditStructure) throw new InvalidOperationException(_lockedMessage + "remove)");
if (Count == 0) throw new InvalidOperationException("Collection is already empty");
if (index >= 0 && index < Count) _items.RemoveAt(index);
else throw new ArgumentOutOfRangeException("index", "Invalid index value, (0-" + (Count - 1) + ")");
}
#region IEnumerable<Resource> Members
/// <summary>Returns an enumerator that iterations through the collection</summary>
/// <returns>The enumerator</returns>
public IEnumerator<Resource> GetEnumerator()
{
return _items.GetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _items.GetEnumerator();
}
#endregion
}
}