1 ////////////////////////////////////////////////////////////////////////////////
2 //                                                                            //
3 // MIT X11 license, Copyright (c) 2005-2006 by:                               //
4 //                                                                            //
5 // Authors:                                                                   //
6 //      Michael Dominic K. <michaldominik@gmail.com>                          //
7 //                                                                            //
8 // Permission is hereby granted, free of charge, to any person obtaining a    //
9 // copy of this software and associated documentation files (the "Software"), //
10 // to deal in the Software without restriction, including without limitation  //
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,   //
12 // and/or sell copies of the Software, and to permit persons to whom the      //
13 // Software is furnished to do so, subject to the following conditions:       //
14 //                                                                            //
15 // The above copyright notice and this permission notice shall be included    //
16 // in all copies or substantial portions of the Software.                     //
17 //                                                                            //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS    //
19 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                 //
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN  //
21 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   //
22 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      //
23 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  //
24 // USE OR OTHER DEALINGS IN THE SOFTWARE.                                     //
25 //                                                                            //
26 ////////////////////////////////////////////////////////////////////////////////
27 
28 namespace Diva.Core {
29 
30         using System;
31         using Widgets;
32         using System.Xml;
33         using Util;
34         using System.Collections.Generic;
35         using System.Collections;
36         using Basics;
37 
38         public class OpenerTask : Task, IBoilProvider {
39 
40                 // Private structs ////////////////////////////////////////////
41 
42                 struct ObjectInfo {
43 
44                         public ObjectContainer Container;
45                         public int[] Depends;
46                         public string SystemType;
47                         public int RefId;
48 
49                         /* CONSTRUCTOR */
ObjectInfoDiva.Core.OpenerTask.ObjectInfo50                         public ObjectInfo (ObjectContainer container)
51                         {
52                                 Container = container;
53                                 Depends = container.Depends.ToArray ();
54                                 SystemType = container.SystemType;
55                                 RefId = container.RefId;
56                         }
57 
ToStringDiva.Core.OpenerTask.ObjectInfo58                         public override string ToString ()
59                         {
60                                 return String.Format ("Type: {0} Deps count: {1} Id: {2}",
61                                                       SystemType, Depends.Length, RefId);
62                         }
63 
IsUnBoilableDiva.Core.OpenerTask.ObjectInfo64                         public bool IsUnBoilable (IBoilProvider provider)
65                         {
66                                 if (Depends.Length == 0)
67                                         return true;
68 
69                                 foreach (int id in Depends)
70                                         if (! (provider.Contains (id)))
71                                                 return false;
72 
73                                 return true;
74                         }
75 
76                 }
77 
78                 // Enums //////////////////////////////////////////////////////
79 
80                 enum OpenerTaskStep { Init, Header, ProjectInfoRead, ObjectListRead,
81                                       ObjectListParse, ObjectListUnBoil, FindRoots,
82                                       Finished };
83 
84                 // Fields /////////////////////////////////////////////////////
85 
86                 string fileName;                         // Filename we're reading
87                 XmlDocument xmlDocument;                 // Our document
88                 //XmlNode projectInfoNode;               // <projectinfo> node
89                 IEnumerator objectsEnumerator;           // Enumerator
90                 List <ObjectInfo> objectsList;           // Objects list
91                 ObjectListContainer objectListContainer;
92                 OpenerTaskStep currentStep;              // Our current step
93 
94                 Dictionary <int, object> idToObject;     // Id -> object
95                 Dictionary <object, int> objectToId;     // Object -> Id
96 
97                 string projectName = String.Empty;
98                 string projectDirectory = String.Empty;
99                 TagList projectTagList;
100                 StuffList projectStuffList;
101                 TrackList projectTrackList;
102                 ClipList projectClipList;
103                 MediaItemList projectMediaItemList;
104                 Commander projectCommander;
105                 Gdv.Pipeline projectPipeline;
106                 Gdv.ProjectFormat projectFormat;
107 
108                 // Properties /////////////////////////////////////////////////
109 
110                 public string ProjectName {
111                         get { return projectName; }
112                 }
113 
114                 public string ProjectDirectory {
115                         get { return projectDirectory; }
116                 }
117 
118                 public TagList ProjectTagList {
119                         get { return projectTagList; }
120                 }
121 
122                 public StuffList ProjectStuffList {
123                         get { return projectStuffList; }
124                 }
125 
126                 public TrackList ProjectTrackList {
127                         get { return projectTrackList; }
128                 }
129 
130                 public ClipList ProjectClipList {
131                         get { return projectClipList; }
132                 }
133 
134                 public MediaItemList ProjectMediaItemList {
135                         get { return projectMediaItemList; }
136                 }
137 
138                 public Commander ProjectCommander {
139                         get { return projectCommander; }
140                 }
141 
142                 public Gdv.Pipeline ProjectPipeline {
143                         get { return projectPipeline; }
144                 }
145 
146                 public Gdv.ProjectFormat ProjectFormat {
147                         get { return projectFormat; }
148                 }
149 
150                 // Public methods /////////////////////////////////////////////
151 
152                 /* CONSTRUCTOR */
OpenerTask(string fileName)153                 public OpenerTask (string fileName)
154                 {
155                         this.fileName = fileName;
156                         var verbatimString = @"c:\test\";
157 
158                         var verbatimStringWithNewline = @"test \\ \n \t \r
159 a
160 b
161 c";
162                         var verbatimStringWithEscapedQuotes = @"He said
163 ""she says \"" is not an escaped character in verbatimstrings""
164 ";
165 
166                         int[] numbers = { 5,6,4,2,4,6,8,9,7,0 };
167                         var linqExample = from n in numbers
168                                           where n > 5
169                                           select n;
170 
171                         var anotherlinqExample = from n in numbers
172                                                  orderby n descending
173                                                  select n;
174 
175                         int[] someMoreNumbers = { 8,2,17,34,8,9,9,5,3,4,2,1,5 };
176                         var moreLinq = from n in numbers
177                                        join mn in moreNumbers on n equals mn + 2
178                                        select new {n, mn};
179                 }
180 
181                 public override void Reset ()
182                 {
183                         objectToId = new Dictionary <object, int> ();
184                         idToObject = new Dictionary <int, object> ();
185 
186                         xmlDocument = null;
187                         //projectInfoNode = null;
188 
189                         currentStep = OpenerTaskStep.Init;
190 
191                         base.Reset ();
192                 }
193 
194                 public int GetIdForObject (object o)
195                 {
196                         return objectToId [o];
197                 }
198 
199                 public object GetObjectForId (int id)
200                 {
201                         return idToObject [id];
202                 }
203 
204                 public bool Contains (int id)
205                 {
206                         return idToObject.ContainsKey (id);
207                 }
208 
209                 // Private methods ////////////////////////////////////////////
210 
211                 protected override TaskStatus ExecuteStep (int s)
212                 {
213                         bool cont = true;
214 
215                         // Main
216                         switch (currentStep) {
217 
218                                 case OpenerTaskStep.Init:
219                                         objectsList = new List <ObjectInfo> ();
220                                         xmlDocument = new XmlDocument ();
221                                         xmlDocument.Load (fileName);
222                                         currentStep = OpenerTaskStep.Header;
223                                         break;
224 
225                                 case OpenerTaskStep.Header:
226                                         //ReadHeader ();
227                                         currentStep = OpenerTaskStep.ProjectInfoRead;
228                                         break;
229 
230                                 case OpenerTaskStep.ProjectInfoRead:
231                                         foreach (XmlNode node in xmlDocument.DocumentElement.ChildNodes)
232                                                 if (node.Name == "projectinfo")
233                                                         ResolveProjectInfoNode (node);
234 
235                                         // FIXME: Fail if not found/not resolved
236                                         currentStep = OpenerTaskStep.ObjectListRead;
237                                         break;
238 
239                                 case OpenerTaskStep.ObjectListRead:
240                                         foreach (XmlNode node in xmlDocument.DocumentElement.ChildNodes)
241                                                 if (node.Name == "objectlist")
242                                                         objectListContainer = (ObjectListContainer)
243                                                                 DataFactory.MakeDataElement  (node as XmlElement);
244 
245                                         if (objectListContainer == null)
246                                                 throw new Exception ("ObjectListContainer not found!");
247 
248                                         currentStep = OpenerTaskStep.ObjectListParse;
249                                         break;
250 
251                                 case OpenerTaskStep.ObjectListParse:
252                                         bool flush = EnumerateSomeObjects ();
253                                         if (flush)
254                                                 currentStep = OpenerTaskStep.ObjectListUnBoil;
255                                         break;
256 
257                                 case OpenerTaskStep.ObjectListUnBoil:
258                                         bool done = UnBoilSomeObjects ();
259                                         if (done)
260                                                 currentStep = OpenerTaskStep.FindRoots;
261                                         break;
262 
263 
264                                 case OpenerTaskStep.FindRoots:
265                                         projectTrackList = (TrackList) FindRoot ("tracklist");
266                                         projectTagList = (TagList) FindRoot ("taglist");
267                                         projectStuffList = (StuffList) FindRoot ("stufflist");
268                                         projectClipList = (ClipList) FindRoot ("cliplist");
269                                         projectMediaItemList = (MediaItemList) FindRoot ("mediaitemlist");
270                                         projectPipeline = (Gdv.Pipeline) FindRoot ("pipeline");
271                                         projectCommander = (Commander) FindRoot ("commander");
272                                         projectFormat = (Gdv.ProjectFormat) FindRoot ("projectformat");
273 
274                                         currentStep = OpenerTaskStep.Finished;
275                                         break;
276 
277                                 case OpenerTaskStep.Finished:
278                                         cont = false;
279                                         break;
280 
281                                 default:
282                                         break;
283                         }
284 
285                         // Post
286                         if (cont)
287                                 return TaskStatus.Running;
288                         else
289                                 return TaskStatus.Done;
290                 }
291 
292                 /*
293                 void ReadHeader ()
294                 {
295                         // FIXME: Read all the attributes from the <divaproject> element
296                         }*/
297 
298                 void ResolveProjectInfoNode (XmlNode node)
299                 {
300                         foreach (XmlNode childNode in node) {
301 
302                                 switch (childNode.Name) {
303 
304                                         case "name":
305                                                 projectName = childNode.FirstChild.Value;
306                                                 break;
307 
308                                         case "directory":
309                                                 projectDirectory = childNode.FirstChild.Value;
310                                                 break;
311 
312                                                 // FIXME: Duration etc.
313                                 }
314                         }
315                 }
316 
317                 bool EnumerateSomeObjects ()
318                 {
319                         if (objectsEnumerator == null)
320                                 objectsEnumerator = objectListContainer.FindAllObjects ().GetEnumerator ();
321 
322                         for (int i = 0; i < 10; i++) {
323                                 if (objectsEnumerator.MoveNext () == false)
324                                         return true;
325 
326                                 ObjectContainer container = (ObjectContainer)
327                                         objectsEnumerator.Current;
328 
329                                 ObjectInfo newInfo = new ObjectInfo (container);
330                                 objectsList.Add (newInfo);
331                         }
332 
333                         return false;
334                 }
335 
336                 ObjectInfo GetNextCandidate ()
337                 {
338                         foreach (ObjectInfo objInfo in objectsList)
339                                 if (objInfo.IsUnBoilable (this))
340                                         return objInfo;
341 
342                         throw new Exception ("FIXME: No more unboilable objects found. Recursive?");
343                 }
344 
345                 bool UnBoilSomeObjects ()
346                 {
347                         for (int i = 0; i < 5; i++) {
348                                 // All unboiled
349                                 if (objectsList.Count == 0)
350                                         return true;
351 
352                                 ObjectInfo objInfo = GetNextCandidate ();
353 
354                                 object o = BoilFactory.UnBoil (objInfo.Container, this);
355                                 objectsList.Remove (objInfo);
356 
357                                 // Add
358                                 idToObject [objInfo.RefId] = o;
359                                 objectToId [o] = objInfo.RefId;
360 
361                         }
362 
363                         return false;
364                 }
365 
366                 object FindRoot (string rootString)
367                 {
368                         ObjectContainer container = objectListContainer.FindObjectContainer (rootString);
369                         return idToObject [container.RefId];
370                 }
371 
372         }
373 
374 }
375