2ef18671dd3bc445794fd82807ee39e335698c58
[pithos-ms-client] / trunk%2FPithos.Client.WPF%2FSelectiveSynch%2FDirectoryRecord.cs
1 #region
2 /* -----------------------------------------------------------------------
3  * <copyright file="DirectoryRecord.cs" company="GRNet">
4  * 
5  * Copyright 2011-2012 GRNET S.A. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or
8  * without modification, are permitted provided that the following
9  * conditions are met:
10  *
11  *   1. Redistributions of source code must retain the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer.
14  *
15  *   2. Redistributions in binary form must reproduce the above
16  *      copyright notice, this list of conditions and the following
17  *      disclaimer in the documentation and/or other materials
18  *      provided with the distribution.
19  *
20  *
21  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
22  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
25  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * The views and conclusions contained in the software and
35  * documentation are those of the authors and should not be
36  * interpreted as representing official policies, either expressed
37  * or implied, of GRNET S.A.
38  * </copyright>
39  * -----------------------------------------------------------------------
40  */
41 #endregion
42 using System;
43 using System.Collections;
44 using System.Collections.Generic;
45 using System.Collections.Specialized;
46 using System.IO;
47 using System.Linq;
48 using System.Text;
49 using Caliburn.Micro;
50 using Pithos.Client.WPF.Utils;
51 using Pithos.Core.Agents;
52 using Pithos.Interfaces;
53
54 namespace Pithos.Client.WPF.SelectiveSynch
55 {
56     public class DirectoryRecord :PropertyChangedBase, IEnumerable<DirectoryRecord>
57     {
58         private ObjectInfo _objectInfo;
59         public ObjectInfo ObjectInfo
60         {
61             get { return _objectInfo; }
62             set
63             {
64                 _objectInfo = value;
65                 Uri = value.Uri;
66             }
67         }
68
69         public Uri Uri { get; set; }
70         //public DirectoryInfo LocalInfo { get; set; }
71
72         DirectoryRecord _parent;
73
74         public bool Added { get; set; }
75         public bool Removed { get; set; }
76
77         private bool? _isChecked=true;
78         #region IsChecked
79
80         /// <summary>
81         /// Gets/sets the state of the associated UI toggle (ex. CheckBox).
82         /// The return value is calculated based on the check state of all
83         /// child FooViewModels.  Setting this property to true or false
84         /// will set all children to the same check state, and setting it 
85         /// to any value will cause the parent to verify its check state.
86         /// </summary>
87         public bool? IsChecked
88         {
89             get { return _isChecked; }
90             set { this.SetIsChecked(value, true, true); }
91         }
92
93         void SetIsChecked(bool? value, bool updateChildren, bool updateParent)
94         {
95             if (value == _isChecked)
96                 return;
97
98             _isChecked = value;
99
100             //If the value is null both Added and Removed should be False
101             Added = _isChecked??false;
102             Removed = !(_isChecked??true);
103
104             if (updateChildren && _isChecked.HasValue)
105                 this.Directories.Apply(c => c.SetIsChecked(_isChecked, true, false));
106
107             if (updateParent && _parent != null)
108                 _parent.VerifyCheckState();
109
110             this.RaisePropertyChangedEventImmediately("IsChecked");
111         }
112
113         void VerifyCheckState()
114         {
115             bool? state = null;
116             for (var i = 0; i < this.Directories.Count(); ++i)
117             {
118                 bool? current = this.Directories.ElementAt(i).IsChecked;
119                 if (i == 0)
120                 {
121                     state = current;
122                 }
123                 else if (state != current)
124                 {
125                     state = null;
126                     break;
127                 }
128             }
129             this.SetIsChecked(state, false, true);
130         }
131
132         #endregion // IsChecked
133
134
135         public bool IsInitiallySelected { get; private set; }
136
137         private List<DirectoryRecord>  _directories=new List<DirectoryRecord>();
138         public List<DirectoryRecord> Directories
139         {
140             get { return _directories; }
141             set { _directories= value; }
142         }
143
144         public DirectoryRecord()
145         {
146             
147 /*
148              _directories = new Lazy<List<DirectoryRecord>>(() => 
149                 new List<DirectoryRecord>());
150 */
151 /*
152              _directories = new Lazy<List<DirectoryRecord>>(() => 
153                 (from directory in Info.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
154                 where !directory.FullName.StartsWith(ignorePath)
155                 select new DirectoryRecord(ignorePath) { Info = directory }).ToList());
156 */
157         }
158
159         private string _displayName;
160
161         public string DisplayName
162         {
163             get
164             {
165                 if (ObjectInfo != null)
166                     return ObjectInfo.Name;
167                 return _displayName;
168             }
169             set { _displayName = value; }
170         }
171
172         public DirectoryRecord(ObjectInfo info)
173         {
174             ObjectInfo = info;
175         }
176
177
178 /*
179         public IEnumerable<DirectoryInfo> GetCheckedDirectories()
180         {
181             var q = from record in this
182                     where record.IsChecked==true
183                     select record.Info;
184             return q;
185         }
186 */
187
188 /*
189         public void SetSelections(StringCollection selections)
190         {
191             IsChecked=selections.Contains(Info.FullName);                
192             foreach (var children in Directories)
193             {
194                 children.SetSelections(selections);
195             }
196         }
197 */
198
199
200         public IEnumerator<DirectoryRecord> GetEnumerator()
201         {
202             yield return this;
203             foreach (var children in Directories)
204                 foreach (var info in children)
205                 {
206                     yield return info;
207                 }
208         }
209
210         IEnumerator IEnumerable.GetEnumerator()
211         {
212             return GetEnumerator();
213         }
214
215         public override int GetHashCode()
216         {
217             return ObjectInfo.GetHashCode();
218         }
219
220         public override bool Equals(object obj)
221         {
222             if (!(obj is DirectoryRecord))
223                 return false;
224             var other = (DirectoryRecord)obj;
225             if (Uri != other.Uri)
226                 return false;
227             if (ObjectInfo== null ^ other.ObjectInfo== null)
228                 return false;
229
230             if (ObjectInfo!= null && !ObjectInfo.Equals(other.ObjectInfo))
231                 return false;
232             var thisEnum = GetEnumerator();
233             var otherEnum = other.GetEnumerator();
234             //Skipt the first item, it is the current node itself
235             thisEnum.MoveNext();
236             otherEnum.MoveNext();
237             while (true)
238             {
239                 var thisMove = thisEnum.MoveNext();
240                 var otherMove = otherEnum.MoveNext();
241
242                 if (thisMove ^ otherMove)
243                     return false;
244                 if (!thisMove)
245                     return true;
246
247                 if (!thisEnum.Current.Equals(otherEnum.Current))
248                     return false;
249             }
250         }
251     }
252 }