1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2008 Novell, Inc.
21 //
22 // Authors:
23 //	Andreia Gaita (avidigal@novell.com)
24 //
25 
26 using System;
27 using System.Collections;
28 using Mono.WebBrowser;
29 using Mono.WebBrowser.DOM;
30 
31 namespace Mono.Mozilla.DOM
32 {
33 	internal class WindowCollection : DOMObject, IWindowCollection
34 	{
35 		protected nsIDOMWindowCollection unmanagedWindows;
36 		protected IWindow [] windows;
37 		protected int windowCount;
38 
WindowCollection(WebBrowser control, nsIDOMWindowCollection windowCol)39 		public WindowCollection (WebBrowser control, nsIDOMWindowCollection windowCol) : base (control)
40 		{
41 			if (control.platform != control.enginePlatform)
42 				unmanagedWindows = nsDOMWindowCollection.GetProxy (control, windowCol);
43 			else
44 				unmanagedWindows = windowCol;
45 		}
46 
WindowCollection(WebBrowser control)47 		public WindowCollection (WebBrowser control) : base (control)
48 		{
49 			windows = new Window[0];
50 		}
51 
52 		#region IDisposable Members
Dispose(bool disposing)53 		protected override  void Dispose (bool disposing)
54 		{
55 			if (!disposed) {
56 				if (disposing) {
57 					Clear ();
58 				}
59 			}
60 			base.Dispose(disposing);
61 		}
62 		#endregion
63 
64 		#region Helpers
Clear()65 		protected void Clear ()
66 		{
67 			if (windows != null) {
68 				for (int i = 0; i < windowCount; i++) {
69 					windows[i] = null;
70 				}
71 				windowCount = 0;
72 				windows = null;
73 			}
74 		}
75 
Load()76 		internal void Load ()
77 		{
78 			Clear ();
79 			uint count;
80 			unmanagedWindows.getLength (out count);
81 			Window[] tmpwindows = new Window[count];
82 			for (int i = 0; i < count;i++) {
83 				nsIDOMWindow window;
84 				unmanagedWindows.item ((uint)i, out window);
85 				tmpwindows[windowCount++] = new Window (control, (nsIDOMWindow)window);
86 			}
87 			windows = new Window[windowCount];
88 			Array.Copy (tmpwindows, windows, windowCount);
89 		}
90 		#endregion
91 
92 		#region IEnumerable members
GetEnumerator()93 		public IEnumerator GetEnumerator ()
94 		{
95 			return new WindowEnumerator (this);
96 		}
97 		#endregion
98 
99 		#region ICollection members
CopyTo(Array dest, int index)100 		public void CopyTo (Array dest, int index)
101 		{
102 			if (windows != null) {
103 				Array.Copy (windows, 0, dest, index, windowCount);
104 			}
105 		}
106 
107 		public int Count {
108 			get {
109 				if (unmanagedWindows != null && windows == null)
110 					Load ();
111 				return windowCount;
112 			}
113 		}
114 
115 		object ICollection.SyncRoot {
116 			get { return this; }
117 		}
118 
119 		bool ICollection.IsSynchronized {
120 			get { return false; }
121 		}
122 
123 		#endregion
124 
125 		#region IList members
126 		public bool IsReadOnly
127 		{
128 			get { return false;}
129 		}
130 
131 		bool IList.IsFixedSize
132 		{
133 			get { return false;}
134 		}
135 
IList.RemoveAt(int index)136 		void IList.RemoveAt  (int index)
137 		{
138 			RemoveAt (index);
139 		}
140 
RemoveAt(int index)141 		public void RemoveAt (int index)
142 		{
143 			if (index > windowCount || index < 0)
144 				return;
145 			Array.Copy (windows, index + 1, windows, index, (windowCount - index) - 1);
146 			windowCount--;
147 			windows[windowCount] = null;
148 		}
149 
Remove(IWindow window)150 		public void Remove (IWindow window)
151 		{
152 			this.RemoveAt (IndexOf (window));
153 		}
154 
IList.Remove(object window)155 		void IList.Remove (object window)
156 		{
157 			Remove (window as IWindow);
158 		}
159 
Insert(int index, IWindow value)160 		public void Insert (int index, IWindow value)
161 		{
162 			if (index > windowCount)
163 				index = windowCount;
164 			IWindow[] tmp = new Window[windowCount+1];
165 			if (index > 0)
166 				Array.Copy (windows, 0, tmp, 0, index);
167 			tmp[index] = value;
168 			if (index < windowCount)
169 				Array.Copy (windows, index, tmp, index + 1, (windowCount - index));
170 			windows = tmp;
171 			windowCount++;
172 		}
173 
IList.Insert(int index, object value)174 		void IList.Insert (int index, object value)
175 		{
176 			this.Insert (index, value as IWindow);
177 		}
178 
IndexOf(IWindow window)179 		public int IndexOf (IWindow window)
180 		{
181 			return Array.IndexOf (windows, window);
182 		}
183 
IList.IndexOf(object window)184 		int IList.IndexOf (object window)
185 		{
186 			return IndexOf (window as IWindow);
187 		}
188 
189 
Contains(IWindow window)190 		public bool Contains (IWindow window)
191 		{
192 			return this.IndexOf (window) != -1;
193 		}
194 
IList.Contains(object window)195 		bool IList.Contains (object window)
196 		{
197 			return Contains (window as IWindow);
198 		}
199 
IList.Clear()200 		void IList.Clear ()
201 		{
202 			this.Clear ();
203 		}
204 
Add(IWindow window)205 		public int Add (IWindow window)
206 		{
207 			this.Insert (windowCount + 1, window as IWindow);
208 			return windowCount - 1;
209 		}
210 
IList.Add(object window)211 		int IList.Add (object window)
212 		{
213 			return Add (window as IWindow);
214 		}
215 
216 		object IList.this [int index] {
217 			get {
218 				return this [index];
219 			}
220 			set {
221 				this [index] = value as IWindow;
222 			}
223 		}
224 
225 		public IWindow this [int index] {
226 			get {
227 				if (index < 0 || index >= windowCount)
228 					throw new ArgumentOutOfRangeException ("index");
229 				return windows [index];
230 			}
231 			set {
232 				if (index < 0 || index >= windowCount)
233 					throw new ArgumentOutOfRangeException ("index");
234 				windows [index] = value as IWindow;
235 			}
236 		}
237 
238 		#endregion
239 
GetHashCode()240 		public override int GetHashCode () {
241 			if (this.unmanagedWindows != null)
242 				return this.unmanagedWindows.GetHashCode ();
243 			return base.GetHashCode ();
244 		}
245 
246 		internal class WindowEnumerator : IEnumerator {
247 
248 			private WindowCollection collection;
249 			private int index = -1;
250 
WindowEnumerator(WindowCollection collection)251 			public WindowEnumerator (WindowCollection collection)
252 			{
253 				this.collection = collection;
254 			}
255 
256 			public object Current {
257 				get {
258 					if (index == -1)
259 						return null;
260 					return collection [index];
261 				}
262 			}
263 
MoveNext()264 			public bool MoveNext ()
265 			{
266 				if (index + 1 >= collection.Count)
267 					return false;
268 				index++;
269 				return true;
270 			}
271 
Reset()272 			public void Reset ()
273 			{
274 				index = -1;
275 			}
276 		}
277 
278 	}
279 }
280