Compute lucene-style scores for our hits.
[beagle.git] / Tiles / TileHitCollection.cs
bloba5bdd7087efd7f808b7a3c8afe0fc23d08f8f482
1 //
2 // TileHitCollection.cs
3 //
4 // Copyright (C) 2004 Novell, Inc.
5 //
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:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
27 using System;
28 using System.Collections;
30 namespace Beagle.Tile {
32 [TileStyle (Resource="template-page.css")]
33 public class TileHitCollection : Tile {
35 public TileHitCollection () {
38 private class HitTilePair : IComparable {
39 Hit hit;
40 Tile tile;
42 public HitTilePair (Hit _hit, Tile _tile)
44 hit = _hit;
45 tile = _tile;
48 public Beagle.Hit Hit {
49 get { return hit; }
52 public Tile Tile {
53 get { return tile; }
56 public int CompareTo (object obj)
58 HitTilePair other = (HitTilePair) obj;
59 return hit.CompareTo (other.hit);
63 private ArrayList all_hits = new ArrayList ();
64 private ArrayList hits = new ArrayList ();
65 int firstDisplayed = 0;
66 int maxDisplayed = 5;
68 Template head_template;
69 Template foot_template;
71 public double MaxScore {
72 get {
73 if (all_hits.Count == 0)
74 return 0;
75 HitTilePair pair = (HitTilePair) all_hits [0];
76 return pair.Hit.Score;
80 public int FirstDisplayed {
81 get { return firstDisplayed; }
84 public int LastDisplayed {
85 get { return Math.Min (firstDisplayed + maxDisplayed, hits.Count) - 1; }
88 public int NumDisplayableResults {
89 get { return hits.Count; }
92 public int NumResults {
93 get { return all_hits.Count; }
96 public bool CanPageForward {
97 get { return LastDisplayed != (hits.Count - 1); }
100 [TileAction]
101 public void PageFirst ()
103 firstDisplayed = 0;
104 Changed ();
107 [TileAction]
108 public void PageForward ()
110 firstDisplayed += maxDisplayed;
111 if (firstDisplayed < 0)
112 firstDisplayed = 0;
113 Changed ();
116 public bool CanPageBack {
117 get { return FirstDisplayed > 0; }
120 [TileAction]
121 public void PageBack ()
123 firstDisplayed -= maxDisplayed;
124 if (firstDisplayed < 0)
125 firstDisplayed = 0;
126 Changed ();
129 public void Clear ()
131 bool changed = false;
132 lock (this) {
133 if (all_hits.Count > 0) {
134 all_hits.Clear ();
135 firstDisplayed = 0;
136 changed = true;
138 if (hits.Count > 0) {
139 hits.Clear ();
140 firstDisplayed = 0;
141 changed = true;
144 if (changed)
145 Changed ();
148 private bool InsertDisplayable (HitTilePair pair)
150 int i = hits.BinarySearch (pair);
152 hits.Insert (i < 0 ? ~i : i, pair);
153 if (i == 0 || i < LastDisplayed) {
154 Changed ();
155 return true;
158 return false;
161 public bool Add (Hit hit, Tile tile)
163 bool changed = false;
165 HitTilePair pair = new HitTilePair (hit, tile);
166 int i = all_hits.BinarySearch (pair);
167 all_hits.Insert (i < 0 ? ~i : i, pair);
168 if (i == 0 || i < LastDisplayed) {
169 Changed ();
170 changed = true;
173 if (SourceIsDisplayable (hit)) {
174 if (InsertDisplayable (pair))
175 changed = true;
178 return changed;
181 public bool Subtract (Uri uri)
183 bool removed = false;
185 for (int i = 0; i < all_hits.Count; ++i) {
186 HitTilePair pair = (HitTilePair) all_hits [i];
187 if (pair.Hit.Uri.Equals (uri) && pair.Hit.Uri.Fragment == uri.Fragment) {
188 all_hits.Remove (pair);
189 removed = true;
190 break;
194 for (int i = 0; i < hits.Count; ++i) {
195 HitTilePair pair = (HitTilePair) hits [i];
196 if (pair.Hit.Uri.Equals (uri) && pair.Hit.Uri.Fragment == uri.Fragment) {
197 hits.Remove (pair);
198 break;
202 return removed;
205 public bool IsEmpty {
206 get { return all_hits.Count == 0; }
209 private ArrayList hitSources = new ArrayList ();
211 public void SetSource (string source)
213 Console.WriteLine ("SetSource: {0}", source);
215 hitSources = new ArrayList ();
217 if (source != null)
218 hitSources.Add (source);
220 hits = new ArrayList ();
221 for (int i = 0; i < NumResults; i ++) {
222 HitTilePair pair = (HitTilePair) all_hits [i];
224 if (SourceIsDisplayable (pair.Hit)) {
225 InsertDisplayable (pair);
226 } else
227 Console.WriteLine ("{0} -- {1}", pair.Hit.Type, pair.Hit.Uri);
230 Changed ();
233 public void AddSource (string source)
235 hitSources.Add (source);
237 for (int i = 0; i < NumDisplayableResults; i ++) {
238 HitTilePair pair = (HitTilePair) hits [i];
240 if (! SourceIsDisplayable (pair.Hit))
241 hits.RemoveAt (i);
245 public void SubtractSource (string source)
247 hitSources.Remove (source);
249 for (int i = 0; i < NumResults; i ++) {
250 HitTilePair pair = (HitTilePair) hits [i];
252 if (pair.Hit.Source != source)
253 continue;
255 int j = hits.BinarySearch (pair);
257 hits.Insert (j < 0 ? ~j : j, pair);
258 if (j == 0 || j < LastDisplayed)
259 Changed ();
263 public void ClearSources (string source)
265 if (hitSources.Count == 0)
266 return;
268 hitSources.Clear ();
270 Changed ();
273 public bool SourceIsDisplayable (Hit hit)
275 if (hitSources.Count == 0)
276 return true;
278 if (hitSources.IndexOf (hit.Type) >= 0)
279 return true;
281 return false;
284 private void RenderTiles (TileRenderContext ctx)
286 int i = FirstDisplayed;
287 int i1 = LastDisplayed;
289 while (i <= i1 && i < NumResults) {
290 HitTilePair pair = (HitTilePair) hits [i];
291 ctx.Tile (pair.Tile);
292 ++i;
296 private void PopulateTemplate (Template t)
300 public override void Render (TileRenderContext ctx)
302 if (head_template == null) {
303 head_template = new Template ("template-head.html");
304 PopulateTemplate (head_template);
307 ctx.Write (head_template.ToString ());
309 RenderTiles (ctx);
311 if (foot_template == null) {
312 foot_template = new Template ("template-foot.html");
313 PopulateTemplate (foot_template);
315 ctx.Write (foot_template.ToString ());