[longomatch] Add new classes for drawing objects



commit 3650c73070778a4e285b146427165748f03d18c2
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date:   Sun Apr 13 19:08:39 2014 +0200

    Add new classes for drawing objects

 LongoMatch.Core/Common/Coordinates.cs              |   19 ++-
 LongoMatch.Core/Common/Enums.cs                    |   32 ++++
 LongoMatch.Core/LongoMatch.Core.mdp                |   13 ++
 LongoMatch.Core/Store/Category.cs                  |    2 +-
 LongoMatch.Core/Store/Drawables/Angle.cs           |   92 ++++++++++++
 LongoMatch.Core/Store/Drawables/Circle.cs          |   74 ++++++++++
 LongoMatch.Core/Store/Drawables/Cross.cs           |   92 ++++++++++++
 LongoMatch.Core/Store/Drawables/Drawable.cs        |   70 +++++++++
 LongoMatch.Core/Store/Drawables/Ellipse.cs         |  125 ++++++++++++++++
 LongoMatch.Core/Store/Drawables/Line.cs            |  123 ++++++++++++++++
 LongoMatch.Core/Store/Drawables/MultiPoints.cs     |   91 ++++++++++++
 LongoMatch.Core/Store/Drawables/Quadrilateral.cs   |  119 ++++++++++++++++
 LongoMatch.Core/Store/Drawables/Rectangle.cs       |  120 ++++++++++++++++
 LongoMatch.Core/Store/Drawables/Selection.cs       |   49 +++++++
 LongoMatch.Core/Store/Drawables/Text.cs            |   44 ++++++
 .../Store/Templates/CategoriesTemplate.cs          |    1 +
 LongoMatch.GUI.Helpers/Misc.cs                     |    6 +-
 LongoMatch.Multimedia/LongoMatch.Multimedia.mdp    |    1 -
 Tests/Core/Drawables/TestAngle.cs                  |   96 +++++++++++++
 Tests/Core/Drawables/TestCircle.cs                 |   81 +++++++++++
 Tests/Core/Drawables/TestCross.cs                  |   35 +++++
 Tests/Core/Drawables/TestDrawable.cs               |   58 ++++++++
 Tests/Core/Drawables/TestEllipse.cs                |   96 +++++++++++++
 Tests/Core/Drawables/TestLine.cs                   |  143 +++++++++++++++++++
 Tests/Core/Drawables/TestMultipoints.cs            |  103 ++++++++++++++
 Tests/Core/Drawables/TestQuadrilateral.cs          |  126 +++++++++++++++++
 Tests/Core/Drawables/TestRectangle.cs              |  149 ++++++++++++++++++++
 Tests/Core/Drawables/TestText.cs                   |   47 ++++++
 Tests/Tests.mdp                                    |   11 ++
 29 files changed, 2010 insertions(+), 8 deletions(-)
---
diff --git a/LongoMatch.Core/Common/Coordinates.cs b/LongoMatch.Core/Common/Coordinates.cs
index 6d2d1fb..5e6f8b9 100644
--- a/LongoMatch.Core/Common/Coordinates.cs
+++ b/LongoMatch.Core/Common/Coordinates.cs
@@ -57,21 +57,26 @@ namespace LongoMatch.Common
        
        [Serializable]
        public class Point {
-               public Point (int x, int y) {
+
+               public Point (double x, double y) {
                        X = x;
                        Y = y;
                }
                
-               public int X {
+               public double X {
                        get;
                        set;
                }
                
-               public int Y {
+               public double Y {
                        get;
                        set;
                }
                
+               public double Distance (Point p) {
+                       return Math.Sqrt (Math.Pow (this.X - p.X, 2) - Math.Pow (this.Y - Y, 2));
+               }
+
                public override string ToString ()
                {
                        return string.Format ("[Point: X={0}, Y={1}]", X, Y);
@@ -90,6 +95,14 @@ namespace LongoMatch.Common
                {
                        return (X.ToString() + "-" + Y.ToString()).GetHashCode();
                }
+               
+               public static bool operator < (Point p1, Point p2) {
+                       return p1.X < p2.X && p1.Y < p2.Y;
+               }
+               
+               public static bool operator > (Point p1, Point p2) {
+                       return p1.X > p2.X && p1.Y > p2.Y;
+               }
        }
 }
 
diff --git a/LongoMatch.Core/Common/Enums.cs b/LongoMatch.Core/Common/Enums.cs
index 20d960a..4c1ba72 100644
--- a/LongoMatch.Core/Common/Enums.cs
+++ b/LongoMatch.Core/Common/Enums.cs
@@ -144,4 +144,36 @@ namespace LongoMatch.Common
                Timeline,
                GameUnits,
        }
+       
+       public enum SelectionPosition {
+               TopLeft,
+               TopRight,
+               BottomLeft,
+               BottomRight,
+               Left,
+               Right,
+               Top,
+               Bottom,
+               LineStart,
+               LineStop,
+               AngleStart,
+               AngleStop,
+               AngleCenter,
+               CircleBorder,
+               All,
+               None,
+       }
+       
+       public enum LineStyle {
+               Normal,
+               Dashed,
+               Pointed
+       }
+       
+       public enum LineType {
+               Simple,
+               Arrow,
+               DoubleArrow,
+               Rounded
+       }
 }
diff --git a/LongoMatch.Core/LongoMatch.Core.mdp b/LongoMatch.Core/LongoMatch.Core.mdp
index a2aad3d..31d48dc 100644
--- a/LongoMatch.Core/LongoMatch.Core.mdp
+++ b/LongoMatch.Core/LongoMatch.Core.mdp
@@ -116,6 +116,18 @@
     <File subtype="Code" buildaction="Compile" name="Interfaces/GUI/IPanel.cs" />
     <File subtype="Code" buildaction="Compile" name="Interfaces/Multimedia/ICapturer.cs" />
     <File subtype="Code" buildaction="Compile" name="Interfaces/Multimedia/IPlayer.cs" />
+    <File subtype="Directory" buildaction="Compile" name="Store/Drawables" />
+    <File subtype="Code" buildaction="Compile" name="Store/Drawables/Quadrilateral.cs" />
+    <File subtype="Code" buildaction="Compile" name="Store/Drawables/Ellipse.cs" />
+    <File subtype="Code" buildaction="Compile" name="Store/Drawables/Line.cs" />
+    <File subtype="Code" buildaction="Compile" name="Store/Drawables/Text.cs" />
+    <File subtype="Code" buildaction="Compile" name="Store/Drawables/MultiPoints.cs" />
+    <File subtype="Code" buildaction="Compile" name="Store/Drawables/Drawable.cs" />
+    <File subtype="Code" buildaction="Compile" name="Store/Drawables/Cross.cs" />
+    <File subtype="Code" buildaction="Compile" name="Store/Drawables/Rectangle.cs" />
+    <File subtype="Code" buildaction="Compile" name="Store/Drawables/Selection.cs" />
+    <File subtype="Code" buildaction="Compile" name="Store/Drawables/Angle.cs" />
+    <File subtype="Code" buildaction="Compile" name="Store/Drawables/Circle.cs" />
   </Contents>
   <References>
     <ProjectReference type="Gac" localcopy="True" refto="System, Version=4.0.0.0, Culture=neutral, 
PublicKeyToken=b77a5c561934e089" />
@@ -126,5 +138,6 @@
     <ProjectReference type="Gac" localcopy="True" refto="gtk-sharp, Version=2.12.0.0, Culture=neutral, 
PublicKeyToken=35e10195dab3c99f" />
     <ProjectReference type="Gac" localcopy="True" refto="System.Drawing, Version=4.0.0.0, Culture=neutral, 
PublicKeyToken=b03f5f7f11d50a3a" />
     <ProjectReference type="Gac" localcopy="False" refto="Newtonsoft.Json, Version=5.0.0.0, Culture=neutral, 
PublicKeyToken=b9a188c8922137c6" />
+    <ProjectReference type="Gac" localcopy="True" refto="nunit.framework" />
   </References>
 </Project>
\ No newline at end of file
diff --git a/LongoMatch.Core/Store/Category.cs b/LongoMatch.Core/Store/Category.cs
index a1145f3..138b3c6 100644
--- a/LongoMatch.Core/Store/Category.cs
+++ b/LongoMatch.Core/Store/Category.cs
@@ -75,7 +75,7 @@ namespace LongoMatch.Store
                /// <summary>
                /// A color to identify plays in this category
                /// </summary>
-               public  Color Color {
+               public  System.Drawing.Color Color {
                        get;
                        set;
                }
diff --git a/LongoMatch.Core/Store/Drawables/Angle.cs b/LongoMatch.Core/Store/Drawables/Angle.cs
new file mode 100644
index 0000000..4fd3b5f
--- /dev/null
+++ b/LongoMatch.Core/Store/Drawables/Angle.cs
@@ -0,0 +1,92 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using Newtonsoft.Json;
+using LongoMatch.Common;
+
+namespace LongoMatch.Store.Drawables
+{
+       public class Angle: Drawable
+       {
+               public Angle ()
+               {
+               }
+
+               public Angle (Point start, Point center, Point stop)
+               {
+                       Start = start;
+                       Center = center;
+                       Stop = stop;
+               }
+               
+               public Point Start {
+                       get;
+                       set;
+               }
+               
+               public Point Center {
+                       get;
+                       set;
+               }
+               
+               public Point Stop {
+                       get;
+                       set;
+               }
+               
+               [JsonIgnore]
+               public double Degrees {
+                       get {
+                               double a = Math.Atan2 (Stop.Y, Stop.X) - Math.Atan2 (Start.Y, Start.X);
+                               if (a < 0) {
+                                       a += 2 * Math.PI;
+                               }
+                               return a;
+                       }
+               }
+               
+               public override Selection GetSelection (Point p, double pr=0.05) {
+                       if (p.Distance (Start) < pr) {
+                               return new Selection (this, SelectionPosition.AngleStart, p.Distance (Start));
+                       } else if (p.Distance (Stop) < pr) {
+                               return new Selection (this, SelectionPosition.AngleStop, p.Distance (Stop));
+                       } else if (p.Distance (Center) < pr) {
+                               return new Selection (this, SelectionPosition.AngleCenter, p.Distance 
(Center));
+                       } else {
+                               return new Selection (this, SelectionPosition.None);
+                       }
+               }
+               
+               public override void Move (Selection sel, Point p, Point start) {
+                       switch (sel.Position) {
+                       case SelectionPosition.AngleStart:
+                               Start = p;
+                               break;
+                       case SelectionPosition.AngleStop:
+                               Stop = p;
+                               break;
+                       case SelectionPosition.AngleCenter:
+                               Center = p;
+                               break;
+                       default:
+                               throw new Exception ("Unsupported move for angle:  " + sel.Position);
+                       }
+               }
+       }
+}
+
diff --git a/LongoMatch.Core/Store/Drawables/Circle.cs b/LongoMatch.Core/Store/Drawables/Circle.cs
new file mode 100644
index 0000000..ec6e2ba
--- /dev/null
+++ b/LongoMatch.Core/Store/Drawables/Circle.cs
@@ -0,0 +1,74 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using LongoMatch.Common;
+using LongoMatch.Store.Drawables;
+
+namespace LongoMatch.Store.Drawables
+{
+       public class Circle: Drawable
+       {
+               public Circle ()
+               {
+               }
+               
+               public Circle (Point center, double radius)
+               {
+                       Center = center;
+                       Radius = radius;
+               }
+               
+               public Point Center {
+                       get;
+                       set;
+               }
+               
+               public double Radius {
+                       get;
+                       set;
+               }
+               
+               public override Selection GetSelection (Point point, double precision)
+               {
+                       double distance = point.Distance (Center);
+                       if (distance > Radius + precision) {
+                               return new Selection (this, SelectionPosition.None);
+                       } else if (distance > Radius - precision ) {
+                               return new Selection (this, SelectionPosition.CircleBorder, distance - 
Radius);
+                       } else {
+                               return new Selection (this, SelectionPosition.All, distance);
+                       }
+               }
+               
+               public override void Move (Selection sel, Point p, Point start)
+               {
+                       switch (sel.Position) {
+                       case SelectionPosition.All:
+                               Center.X +=  p.X - start.X;
+                               Center.Y += p.Y - start.Y;
+                               break;
+                       case SelectionPosition.CircleBorder:
+                               Radius = p.Distance (Center);
+                               break;
+                       default:
+                               throw new Exception ("Unsupported move for circle:  " + sel.Position);
+                       }
+               }
+       }
+}
+
diff --git a/LongoMatch.Core/Store/Drawables/Cross.cs b/LongoMatch.Core/Store/Drawables/Cross.cs
new file mode 100644
index 0000000..2ed7282
--- /dev/null
+++ b/LongoMatch.Core/Store/Drawables/Cross.cs
@@ -0,0 +1,92 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using Newtonsoft.Json;
+using LongoMatch.Common;
+
+namespace LongoMatch.Store.Drawables
+{
+       public class Cross: Line
+       {
+               public Cross ()
+               {
+               }
+               
+               public Cross (Point start, Point stop, LineType type, LineStyle style):
+                       base (start, stop, type, style)
+               {
+               }
+               
+               [JsonIgnore]
+               public Point StartI {
+                       get {
+                               return new Point (Stop.X, Start.Y);
+                       }
+               }
+               
+               [JsonIgnore]
+               public Point StopI {
+                       get {
+                               return new Point (Start.X, Stop.Y);
+                       }
+               }
+               
+               public override Selection GetSelection (Point p, double pr=0.05) {
+                       double d;
+                       
+                       if (MatchPoint (Start, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.TopLeft, d);
+                       } else if (MatchPoint (StartI, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.TopRight, d);
+                       } else if (MatchPoint (Stop, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.BottomRight, d);
+                       } else if (MatchPoint (StopI, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.BottomLeft, d);
+                       } else {
+                               double slope = (Start.Y - Stop.Y) / (Start.X - Stop.Y);
+                               double yi = Start.Y / (slope * Start.X);
+                               d = Math.Abs (p.Y / (slope * p.X) - yi);
+                               if (d < pr) {
+                                       return new Selection (this, SelectionPosition.All, d);
+                               } else {
+                                       return new Selection (this, SelectionPosition.None, d);
+                               }
+                       }
+               }
+               
+               public override void Move (Selection sel, Point p, Point moveStart) {
+                       switch (sel.Position) {
+                       case SelectionPosition.TopLeft:
+                               Start = p;
+                               break;
+                       case SelectionPosition.BottomRight:
+                               Stop = p;
+                               break;
+                       case SelectionPosition.All:
+                               Start.X += p.X - moveStart.X;
+                               Start.Y += p.Y - moveStart.Y;
+                               Stop.X += p.X - moveStart.X;
+                               Stop.Y += p.Y - moveStart.Y;
+                               break;
+                       default:
+                               throw new Exception ("Unsupported move for line:  " + sel.Position);
+                       }
+               }
+       }
+}
+
diff --git a/LongoMatch.Core/Store/Drawables/Drawable.cs b/LongoMatch.Core/Store/Drawables/Drawable.cs
new file mode 100644
index 0000000..fc4b46e
--- /dev/null
+++ b/LongoMatch.Core/Store/Drawables/Drawable.cs
@@ -0,0 +1,70 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+
+using LongoMatch.Common;
+using LongoMatch.Interfaces.Drawing;
+
+namespace LongoMatch.Store.Drawables
+{
+       public abstract class Drawable: IDrawable
+       {
+               public Drawable ()
+               {
+               }
+               
+               public Color StrokeColor {
+                       get;
+                       set;
+               }
+               
+               public uint StrokeSize {
+                       get;
+                       set;
+               }
+               
+               public Color FillColor {
+                       get;
+                       set;
+               }
+               
+               public bool Selected {
+                       get;
+                       set;
+               }
+               
+               public abstract Selection GetSelection (Point point, double precision);
+
+               public abstract void Move (Selection s, Point dst, Point start);
+               
+               public  void Move (SelectionPosition s, Point dst, Point start) {
+                       Move (new Selection (null, s, 0), dst, start);
+               }
+
+               public static bool MatchPoint (Point p1, Point p2, double precision, out double accuracy) {
+                       accuracy = p1.Distance (p2);
+                       return accuracy <= precision;
+               }
+               
+               public static bool MatchAxis (double c1, double c2, double precision, out double accuracy) {
+                               accuracy = Math.Abs (c1 - c2);
+                               return accuracy <= precision;
+               }
+       }
+}
+
diff --git a/LongoMatch.Core/Store/Drawables/Ellipse.cs b/LongoMatch.Core/Store/Drawables/Ellipse.cs
new file mode 100644
index 0000000..f8a0b32
--- /dev/null
+++ b/LongoMatch.Core/Store/Drawables/Ellipse.cs
@@ -0,0 +1,125 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using Newtonsoft.Json;
+using LongoMatch.Common;
+
+namespace LongoMatch.Store.Drawables
+{
+       public class Ellipse: Drawable
+       {
+               public Ellipse ()
+               {
+               }
+
+               public Ellipse (Point center, double axisX, double axisY)
+               {
+                       Center = center;
+                       AxisX = axisX;
+                       AxisY = axisY;
+               }
+               
+               public Point Center {
+                       get;
+                       set;
+               }
+               
+               public double AxisX {
+                       get;
+                       set;
+               }
+               
+               public double AxisY {
+                       get;
+                       set;
+               }
+               
+               [JsonIgnore]
+               public Point Top {
+                       get {
+                               return new Point (Center.X, Center.Y + AxisY);
+                       }
+               }
+               
+               [JsonIgnore]
+               public Point Bottom {
+                       get {
+                               return new Point (Center.X, Center.Y - AxisY);
+                       }
+               }
+               
+               [JsonIgnore]
+               public Point Left {
+                       get {
+                               return new Point (Center.X - AxisX, Center.Y);
+                       }
+               }
+               
+               public Point Right {
+                       get {
+                               return new Point (Center.X + AxisX, Center.Y);
+                       }
+               }
+
+               public override Selection GetSelection (Point p, double pr=0.05) {
+                       double d;
+                       
+                       if (MatchPoint (Top, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.Top, d);
+                       } else if (MatchPoint (Bottom, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.Bottom, d);
+                       } else if (MatchPoint (Left, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.Left, d);
+                       } else if (MatchPoint (Right, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.Right, d);
+                       } else {
+                               /* Ellipse equation */
+                               double a = Math.Pow (p.X - Center.X, 2) / Math.Pow (AxisX, 2);
+                               double b = Math.Pow (p.Y - Center.Y, 2) / Math.Pow (AxisY, 2);
+                               if ((a + b) <= 1) {
+                                       return new Selection (this, SelectionPosition.All, p.Distance 
(Center));
+                               } else {
+                                       return new Selection (this, SelectionPosition.None);
+                               }
+                       }
+               }
+               
+               public override void Move (Selection sel, Point p, Point moveStart) {
+                       switch (sel.Position) {
+                       case SelectionPosition.Top:
+                       case SelectionPosition.Bottom: {
+                               AxisY = Math.Abs (p.Y - Center.Y);
+                               break;
+                       }
+                       case SelectionPosition.Left:
+                       case SelectionPosition.Right: {
+                               AxisX = Math.Abs (p.X - Center.X);
+                               break;
+                       }
+                       case SelectionPosition.All: {
+                               Center.X += p.X - moveStart.X;
+                               Center.Y += p.Y - moveStart.Y;
+                               break;
+                       }
+                       default:
+                               throw new Exception ("Unsupported move for line:  " + sel.Position);
+                       }
+               }
+       }
+}
+
diff --git a/LongoMatch.Core/Store/Drawables/Line.cs b/LongoMatch.Core/Store/Drawables/Line.cs
new file mode 100644
index 0000000..4c14714
--- /dev/null
+++ b/LongoMatch.Core/Store/Drawables/Line.cs
@@ -0,0 +1,123 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using LongoMatch.Common;
+using Newtonsoft.Json;
+
+namespace LongoMatch.Store.Drawables
+{
+       public class Line: Drawable
+       {
+               public Line ()
+               {
+               }
+
+               public Line (Point start, Point stop, LineType type, LineStyle style)
+               {
+                       Start = start;
+                       Stop = stop;
+                       Type = type;
+                       Style = style;
+               }
+               
+               public Point Start {
+                       get;
+                       set;
+               }
+               
+               public Point Stop {
+                       get;
+                       set;
+               }
+               
+               public LineType Type{
+                       get;
+                       set;
+               }
+               
+               public LineStyle Style{
+                       get;
+                       set;
+               }
+               
+               [JsonIgnore]
+               public Point Center {
+                       get {
+                               return new Point (Start.X + (Stop.X - Start.X) / 2,
+                                                 Start.Y + (Stop.Y -Start.Y) / 2);
+                       }
+               }
+               
+               public override Selection GetSelection (Point p, double pr=0.05) {
+                       double d;
+                       
+                       if (MatchPoint (Start, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.LineStart, d);
+                       } else if (MatchPoint (Stop, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.LineStop, d);
+                       } else {
+                               double minx, maxx, miny, maxy;
+                               
+                               minx = Math.Min (Start.X, Stop.X) - pr;
+                               maxx = Math.Max (Start.X, Stop.X) + pr;
+                               miny = Math.Min (Start.Y, Stop.Y) - pr;
+                               maxy = Math.Max (Start.Y, Stop.Y) + pr;
+                               if (p.X < minx || p.X > maxx || p.Y < miny || p.Y > maxy) {
+                                       return new Selection (this, SelectionPosition.None);
+                               }
+                               if (Start.X == Stop.X) {
+                                       d = p.Distance (new Point (Start.X, p.Y));
+                               } else if (Start.Y == Stop.Y) {
+                                       d = p.Distance (new Point (p.X, Start.Y));
+                               } else {
+                                       double yi, slope;
+                                       
+                                       slope = (Start.Y - Stop.Y) / (Start.X - Stop.X);
+                                       yi = Start.Y - (slope * Start.X);
+                                       d = Math.Abs ((slope * p.X) + yi - p.Y);
+                               }
+                               
+                               if (d  < pr) {
+                                       return new Selection (this, SelectionPosition.All, d);
+                               } else {
+                                       return new Selection (this, SelectionPosition.None, 0);
+                               }
+                       }
+               }
+               
+               public override void Move (Selection sel, Point p, Point moveStart) {
+                       switch (sel.Position) {
+                       case SelectionPosition.LineStart:
+                               Start = p;
+                               break;
+                       case SelectionPosition.LineStop:
+                               Stop = p;
+                               break;
+                       case SelectionPosition.All:
+                               Start.X += p.X - moveStart.X;
+                               Start.Y += p.Y - moveStart.Y;
+                               Stop.X += p.X - moveStart.X;
+                               Stop.Y += p.Y - moveStart.Y;
+                               break;
+                       default:
+                               throw new Exception ("Unsupported move for line:  " + sel.Position);
+                       }
+               }
+       }
+}
+
diff --git a/LongoMatch.Core/Store/Drawables/MultiPoints.cs b/LongoMatch.Core/Store/Drawables/MultiPoints.cs
new file mode 100644
index 0000000..0dd9eeb
--- /dev/null
+++ b/LongoMatch.Core/Store/Drawables/MultiPoints.cs
@@ -0,0 +1,91 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using LongoMatch.Common;
+
+namespace LongoMatch.Store.Drawables
+{
+       public class MultiPoints: Rectangle
+       {
+               List<Point> points;
+               
+               public MultiPoints ()
+               {
+               }
+               
+               public MultiPoints (List<Point> points)
+               {
+                       Points = points;
+               }
+               
+               public List<Point> Points {
+                       get {
+                               return points;
+                       }
+                       set {
+                               points = value;
+                               UpdateArea ();
+                       }
+               }
+               
+               public override Selection GetSelection (Point p, double pr)
+               {
+                       Selection s = base.GetSelection (p, pr);
+                       if (s.Position != SelectionPosition.None) {
+                               s.Position = SelectionPosition.All;
+                       }
+                       return s;
+               }
+       
+               public override void Move (Selection sel, Point p, Point moveStart) {
+                       switch (sel.Position) {
+                       case SelectionPosition.All: {
+                               double xdiff, ydiff;
+                               
+                               xdiff = p.X - moveStart.X;
+                               ydiff = p.Y - moveStart.Y;
+                               foreach (Point point in Points) {
+                                       point.X += xdiff;
+                                       point.Y += ydiff;
+                               }
+                               break;
+                       }
+                       default:
+                               throw new Exception ("Unsupported move for multipoints:  " + sel.Position);
+                       }
+               }
+               
+               void UpdateArea () {
+                       double xmin, xmax, ymin, ymax;
+                       List<Point> px, py;
+                       px = Points.OrderBy (p => p.X).ToList();
+                       py = Points.OrderBy (p => p.X).ToList();
+                       xmin = px[0].X;
+                       xmax = px[px.Count-1].X;
+                       ymin = py[0].Y;
+                       ymax = py[py.Count-1].Y; 
+                       BottomLeft = new Point (xmin, ymin);
+                       TopLeft = new Point (xmin, ymax);
+                       TopRight = new Point (xmax, ymax);
+                       BottomRight = new Point (xmax, ymin);
+               } 
+       }
+}
+
diff --git a/LongoMatch.Core/Store/Drawables/Quadrilateral.cs 
b/LongoMatch.Core/Store/Drawables/Quadrilateral.cs
new file mode 100644
index 0000000..385a152
--- /dev/null
+++ b/LongoMatch.Core/Store/Drawables/Quadrilateral.cs
@@ -0,0 +1,119 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using LongoMatch.Common;
+
+namespace LongoMatch.Store.Drawables
+{
+       public class Quadrilateral: Drawable
+       {
+               public Quadrilateral ()
+               {
+               }
+               
+               public Quadrilateral (Point tl, Point tr, Point bl, Point br)
+               {
+                       TopLeft = tl;
+                       TopRight = tr;
+                       BottomLeft = bl;
+                       BottomRight = br;
+               }
+               
+               public Point TopLeft {
+                       get;
+                       set;
+               }
+               
+               public Point TopRight {
+                       get;
+                       set;
+               }
+               
+               public Point BottomLeft  {
+                       get;
+                       set;
+               }
+               
+               public Point BottomRight  {
+                       get;
+                       set;
+               }
+               
+               public override Selection GetSelection (Point p, double pr) {
+                       double xmin, xmax, ymin, ymax;
+                       double d;
+                       
+                       /* Create a rectangle that wraps the quadrilateral */
+                       xmin = Math.Min (BottomLeft.X, TopLeft.X) - pr;
+                       xmax = Math.Max (BottomRight.X, TopRight.X) + pr;
+                       ymin = Math.Min (BottomLeft.Y, BottomRight.Y) - pr;
+                       ymax = Math.Max (TopLeft.Y, TopRight.Y) + pr;
+                       
+                       if (p.X > xmax || p.X < xmin || p.Y < ymin || p.Y > ymax) {
+                               return new Selection (this, SelectionPosition.None, 0);
+                       } else if (MatchPoint (TopLeft, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.TopLeft, d);
+                       } else if (MatchPoint (TopRight, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.TopRight, d);
+                       } else if (MatchPoint (BottomLeft, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.BottomLeft, d);
+                       } else if (MatchPoint (BottomRight, p, pr, out d)) {
+                               return new Selection (this, SelectionPosition.BottomRight, d);
+                       } else {
+                               Point center = new Point ((TopRight.X - TopLeft.X) / 2,
+                                                         (BottomLeft.Y - TopLeft.Y) / 2);
+                               return new Selection (this, SelectionPosition.All, center.Distance (p));
+                       }
+               }
+               
+               public override void Move (Selection sel,  Point p, Point moveStart) {
+                       switch (sel.Position) {
+                       case SelectionPosition.TopLeft:
+                               TopLeft = p;
+                               break;
+                       case SelectionPosition.TopRight:
+                               TopRight = p;
+                               break;
+                       case SelectionPosition.BottomLeft:
+                               BottomLeft = p;
+                               break;
+                       case SelectionPosition.BottomRight:
+                               BottomRight = p;
+                               break;
+                       case SelectionPosition.All: {
+                               double xdiff, ydiff;
+                               
+                               xdiff = p.X - moveStart.X;
+                               ydiff = p.Y - moveStart.Y;
+                               TopLeft.X += xdiff;
+                               TopLeft.Y += ydiff;
+                               TopRight.X += xdiff;
+                               TopRight.Y += ydiff;
+                               BottomRight.X += xdiff;
+                               BottomRight.Y += ydiff;
+                               BottomLeft.X += xdiff;
+                               BottomLeft.Y += ydiff;
+                               break;
+                       }
+                       default:
+                               throw new Exception ("Unsupported move for quadrilateral:  " + sel.Position);
+                       }
+               }
+       }
+}
+
diff --git a/LongoMatch.Core/Store/Drawables/Rectangle.cs b/LongoMatch.Core/Store/Drawables/Rectangle.cs
new file mode 100644
index 0000000..d18caca
--- /dev/null
+++ b/LongoMatch.Core/Store/Drawables/Rectangle.cs
@@ -0,0 +1,120 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using LongoMatch.Common;
+using Newtonsoft.Json;
+
+namespace LongoMatch.Store.Drawables
+{
+       public class Rectangle: Quadrilateral
+       {
+               public Rectangle ()
+               {
+               }
+               
+               public Rectangle (Point origin, double width, double height)
+               {
+                       BottomLeft = origin;
+                       BottomRight = new Point (origin.X + width, origin.Y);
+                       TopLeft = new Point (origin.X, origin.Y + height);
+                       TopRight = new Point (origin.X + width, origin.Y + height);
+               }
+               
+               [JsonIgnore]
+               public double Width {
+                       get {
+                               return TopRight.X - TopLeft.X;
+                       }
+               }
+               
+               [JsonIgnore]
+               public double Height {
+                       get {
+                               return TopLeft.Y - BottomLeft.Y;
+                       }
+               }
+               
+               [JsonIgnore]
+               public Point Center {
+                       get {
+                               return new Point (BottomLeft.X + Width / 2, BottomLeft.Y + Height / 2);
+                       }
+               }
+               
+               public override Selection GetSelection (Point p, double pr=0.05) {
+                       Selection selection;
+                       double d;
+                       
+                       selection = base.GetSelection (p, pr);
+                       
+                       if (selection.Position == SelectionPosition.All) {
+                               if (MatchAxis (p.X, TopLeft.X, pr, out d)) {
+                                       return new Selection (this, SelectionPosition.Left, d);
+                               } else if (MatchAxis (p.X, TopRight.X, pr, out d)) {
+                                       return new Selection (this, SelectionPosition.Right, d);
+                               } else if (MatchAxis (p.Y, TopLeft.Y, pr, out d)) {
+                                       return new Selection (this, SelectionPosition.Top, d);
+                               } else if (MatchAxis (p.Y, BottomLeft.Y, pr, out d)) {
+                                       return new Selection(this, SelectionPosition.Bottom, d);
+                               }
+                       }
+                       return selection;
+               }
+               
+               public override void Move (Selection sel, Point p, Point moveStart) {
+                       switch (sel.Position) {
+                       case SelectionPosition.Left:
+                               TopLeft.X = BottomLeft.X = p.X;
+                               break;
+                       case SelectionPosition.Right:
+                               TopRight.X = BottomRight.X = p.X;
+                               break;
+                       case SelectionPosition.Top:
+                               TopLeft.Y = TopRight.Y = p.Y;
+                               break;
+                       case SelectionPosition.Bottom:
+                               BottomLeft.Y = BottomRight.Y = p.Y;
+                               break;
+                       case SelectionPosition.TopLeft:
+                               TopLeft = p;
+                               TopRight.Y = p.Y;
+                               BottomLeft.X = p.X;
+                               break;
+                       case SelectionPosition.TopRight:
+                               TopRight = p;
+                               TopLeft.Y = p.Y;
+                               BottomRight.X = p.X;
+                               break;
+                       case SelectionPosition.BottomLeft:
+                               BottomLeft = p;
+                               BottomRight.Y = p.Y;
+                               TopLeft.X = p.X;
+                               break;
+                       case SelectionPosition.BottomRight:
+                               BottomRight = p;
+                               BottomLeft.Y = p.Y;
+                               TopRight.X = p.X;
+                               break;
+                       case SelectionPosition.All:
+                               Center.X += p.X - moveStart.X;
+                               Center.Y += p.Y - moveStart.Y;
+                               break;
+                       }
+               }
+       }
+}
diff --git a/LongoMatch.Core/Store/Drawables/Selection.cs b/LongoMatch.Core/Store/Drawables/Selection.cs
new file mode 100644
index 0000000..25913d2
--- /dev/null
+++ b/LongoMatch.Core/Store/Drawables/Selection.cs
@@ -0,0 +1,49 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using LongoMatch.Common;
+using LongoMatch.Interfaces.Drawing;
+
+namespace LongoMatch.Store.Drawables
+{
+       public class Selection
+       {
+               public Selection (IDrawable drawable, SelectionPosition selpos, double accuracy=0)
+               {
+                       Drawable = drawable;
+                       Position = selpos;
+                       Accuracy = accuracy;
+               }
+               
+               public IDrawable Drawable {
+                       get;
+                       set;
+               }
+               
+               public SelectionPosition Position {
+                       get;
+                       set;
+               }
+               
+               public double Accuracy {
+                       get;
+                       set;
+               }
+       }
+}
+
diff --git a/LongoMatch.Core/Store/Drawables/Text.cs b/LongoMatch.Core/Store/Drawables/Text.cs
new file mode 100644
index 0000000..7ae92c3
--- /dev/null
+++ b/LongoMatch.Core/Store/Drawables/Text.cs
@@ -0,0 +1,44 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using LongoMatch.Common;
+
+namespace LongoMatch.Store.Drawables
+{
+       public class Text: Rectangle
+       {
+               public Text () {
+               }
+
+               public Text (Point origin, double width, double height, String text): base (origin, width, 
height)
+               {
+                       Value = text;
+               }
+               
+               public string Value {
+                       get;
+                       set;    
+               }
+               
+               public Color TextColor {
+                       get;
+                       set;
+               }
+       }
+}
+
diff --git a/LongoMatch.Core/Store/Templates/CategoriesTemplate.cs 
b/LongoMatch.Core/Store/Templates/CategoriesTemplate.cs
index d2fc345..dd2e545 100644
--- a/LongoMatch.Core/Store/Templates/CategoriesTemplate.cs
+++ b/LongoMatch.Core/Store/Templates/CategoriesTemplate.cs
@@ -28,6 +28,7 @@ using LongoMatch.Common;
 using LongoMatch.Interfaces;
 
 using Image = LongoMatch.Common.Image;
+using Color = System.Drawing.Color;
 
 namespace LongoMatch.Store.Templates
 {
diff --git a/LongoMatch.GUI.Helpers/Misc.cs b/LongoMatch.GUI.Helpers/Misc.cs
index 7fc60de..bd96e0a 100644
--- a/LongoMatch.GUI.Helpers/Misc.cs
+++ b/LongoMatch.GUI.Helpers/Misc.cs
@@ -84,11 +84,11 @@ namespace LongoMatch.Gui.Helpers
                        }
                }
                
-               public static Color ToGdkColor(System.Drawing.Color color) {
-                       return new Color(color.R, color.G, color.B);
+               public static Gdk.Color ToGdkColor(System.Drawing.Color color) {
+                       return new Gdk.Color(color.R, color.G, color.B);
                }
                
-               public static System.Drawing.Color ToDrawingColor(Color color) {
+               public static System.Drawing.Color ToDrawingColor(Gdk.Color color) {
                        return System.Drawing.Color.FromArgb(
                                ColorHelper.ShortToByte(color.Red),
                                ColorHelper.ShortToByte(color.Green),
diff --git a/LongoMatch.Multimedia/LongoMatch.Multimedia.mdp b/LongoMatch.Multimedia/LongoMatch.Multimedia.mdp
index 6ac8102..74d95ec 100644
--- a/LongoMatch.Multimedia/LongoMatch.Multimedia.mdp
+++ b/LongoMatch.Multimedia/LongoMatch.Multimedia.mdp
@@ -42,7 +42,6 @@
     <File subtype="Directory" buildaction="Compile" name="Utils" />
     <File subtype="Code" buildaction="Compile" name="Utils/VideoDevice.cs" />
     <File subtype="Code" buildaction="Compile" name="Utils/GStreamer.cs" />
-    <File subtype="Directory" buildaction="Compile" name="Interfaces" />
     <File subtype="Code" buildaction="Compile" name="Common/Handlers.cs" />
     <File subtype="Directory" buildaction="Compile" name="Remuxer" />
     <File subtype="Code" buildaction="Compile" name="Remuxer/GstRemuxer.cs" />
diff --git a/Tests/Core/Drawables/TestAngle.cs b/Tests/Core/Drawables/TestAngle.cs
new file mode 100644
index 0000000..84245b3
--- /dev/null
+++ b/Tests/Core/Drawables/TestAngle.cs
@@ -0,0 +1,96 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using NUnit.Framework;
+using LongoMatch.Common;
+using LongoMatch.Store.Drawables;
+
+namespace Tests.Core.Drawables
+{
+       [TestFixture()]
+       public class TestAngle
+       {
+               [Test()]
+               public void TestSerialization ()
+               {
+                       Point start, center, stop;
+                       
+                       start = new Point (0, 10);
+                       stop = new Point (10, 0);
+                       center = new Point (0, 0);
+                       Angle a = new Angle (start, center, stop);
+                       Utils.CheckSerialization (a);
+                       Angle na = Utils.SerializeDeserialize (a);
+                       Assert.AreEqual (na.Center, a.Center);
+                       Assert.AreEqual (na.Start, a.Start);
+                       Assert.AreEqual (na.Stop, a.Stop);
+               }
+               
+               [Test()]
+               public void TestSelection ()
+               {
+                       Point start, center, stop, p;
+                       Selection s;
+                       
+                       start = new Point (0, 10);
+                       stop = new Point (10, 0);
+                       center = new Point (0, 0);
+                       Angle a = new Angle (start, center, stop);
+                       
+                       p = new Point (0.1, 0.3);
+                       s = a.GetSelection (p, 0.5);
+                       Assert.AreEqual (SelectionPosition.AngleCenter, s.Position);
+                       Assert.AreEqual (p.Distance (center), s.Accuracy);
+                       
+                       p = new Point (9.8, 0.3);
+                       s = a.GetSelection (p, 0.5);
+                       Assert.AreEqual (SelectionPosition.AngleStop, s.Position);
+                       Assert.AreEqual (p.Distance (stop), s.Accuracy);
+                       
+                       p = new Point (0.2, 9.9);
+                       s = a.GetSelection (p, 0.5);
+                       Assert.AreEqual (SelectionPosition.AngleStart, s.Position);
+                       Assert.AreEqual (p.Distance (start), s.Accuracy);
+                       
+                       p = new Point (5, 5);
+                       s = a.GetSelection (p, 0.5);
+                       Assert.AreEqual (SelectionPosition.None, s.Position);
+               }
+               
+               [Test()]
+               public void TestMove ()
+               {
+                       Point start, center, stop, p;
+                       
+                       start = new Point (0, 10);
+                       stop = new Point (10, 0);
+                       center = new Point (0, 0);
+                       Angle a = new Angle (start, center, stop);
+                       p = new Point (0, 9);
+                       a.Move (SelectionPosition.AngleStart, p, null);
+                       Assert.AreEqual (p, a.Start);
+                       p = new Point (11, 2);
+                       a.Move (SelectionPosition.AngleStop, p, null);
+                       Assert.AreEqual (p, a.Stop);
+                       p = new Point (2, 2);
+                       a.Move (SelectionPosition.AngleCenter, p, null);
+                       Assert.AreEqual (p, a.Center);
+               }
+       }
+}
+
diff --git a/Tests/Core/Drawables/TestCircle.cs b/Tests/Core/Drawables/TestCircle.cs
new file mode 100644
index 0000000..1219c75
--- /dev/null
+++ b/Tests/Core/Drawables/TestCircle.cs
@@ -0,0 +1,81 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using NUnit.Framework;
+using LongoMatch.Common;
+using LongoMatch.Store.Drawables;
+
+namespace Tests.Core.Drawables
+{
+       [TestFixture()]
+       public class TestCircle
+       {
+               [Test()]
+               public void TestSerialization ()
+               {
+                       Point p = new Point (10, 10);
+                       Circle c = new Circle (p, 5);
+                       Utils.CheckSerialization (c);
+                       Circle nc = Utils.SerializeDeserialize (c);
+                       Assert.AreEqual (nc.Center, c.Center);
+                       Assert.AreEqual (nc.Radius, c.Radius);
+               }
+               
+               [Test()]
+               public void TestMove ()
+               {
+                       Point p = new Point (10, 10);
+                       Circle c = new Circle (p, 5);
+                       Point p2 = new Point (12, 10);
+                       c.Move (SelectionPosition.All, p2, p);
+                       Assert.AreEqual (p2, c.Center);
+                       
+                       p2 = new Point (12, 16);
+                       c.Move (SelectionPosition.CircleBorder, p2, p);
+                       Assert.AreEqual (6, c.Radius);
+                       
+                       p2 = new Point (14, 10);
+                       c.Move (SelectionPosition.CircleBorder, p2, p);
+                       Assert.AreEqual (2, c.Radius);
+               }
+               
+               [Test()]
+               public void TestSelection ()
+               {
+                       Selection s;
+                       Point p1, p2;
+                       Circle c;
+                       
+                       p1 = new Point (10, 10);
+                       c = new Circle (p1, 5);
+                       p2 = new Point (16, 10);
+                       s = c.GetSelection (p2, 0.9);
+                       Assert.AreEqual (SelectionPosition.None, s.Position);
+                       p2 = new Point (15.9, 10);
+                       s = c.GetSelection (p2, 1);
+                       Assert.AreEqual (SelectionPosition.CircleBorder, s.Position);
+                       p2 = new Point (14.1, 10);
+                       s = c.GetSelection (p2, 1);
+                       Assert.AreEqual (SelectionPosition.CircleBorder, s.Position);
+                       p2 = new Point (13, 10);
+                       s = c.GetSelection (p2, 1);
+                       Assert.AreEqual (SelectionPosition.All, s.Position);
+               }
+       }
+}
+
diff --git a/Tests/Core/Drawables/TestCross.cs b/Tests/Core/Drawables/TestCross.cs
new file mode 100644
index 0000000..2ac042b
--- /dev/null
+++ b/Tests/Core/Drawables/TestCross.cs
@@ -0,0 +1,35 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using NUnit.Framework;
+using LongoMatch.Common;
+using LongoMatch.Store.Drawables;
+
+namespace Tests.Core.Drawables
+{
+       [TestFixture()]
+       public class TestCross
+       {
+               [Test()]
+               [Ignore ("FIXME")]
+               public void TestSerialization ()
+               {
+               }
+       }
+}
+
diff --git a/Tests/Core/Drawables/TestDrawable.cs b/Tests/Core/Drawables/TestDrawable.cs
new file mode 100644
index 0000000..c58fdc9
--- /dev/null
+++ b/Tests/Core/Drawables/TestDrawable.cs
@@ -0,0 +1,58 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using NUnit.Framework;
+using LongoMatch.Store.Drawables;
+using LongoMatch.Common;
+
+namespace Tests.Core.Drawables
+{
+       public class DrawableImp: Drawable
+       {
+               public override Selection GetSelection (Point point, double precision)
+               {
+                       throw new System.NotImplementedException ();
+               }
+               
+               public override void Move (Selection sel, Point p, Point start)
+               {
+                       throw new System.NotImplementedException ();
+               }
+       }
+       
+       [TestFixture()]
+       public class TestDrawable
+       {
+               [Test()]
+               public void TestSerialization ()
+               {
+                       Color c1, c2;
+                       c1 = new Color (1, 2, 3, 2);
+                       c2 = new Color (1, 5, 6, 3);
+                       DrawableImp d = new DrawableImp {StrokeColor=c1, StrokeSize=30, FillColor=c2};
+                       
+                       Utils.CheckSerialization (d);
+                       Drawable newD = Utils.SerializeDeserialize (d);
+                       
+                       Assert.AreEqual (d.FillColor, newD.FillColor);
+                       Assert.AreEqual (d.StrokeSize, newD.StrokeSize);
+                       Assert.AreEqual (d.StrokeColor, newD.StrokeColor);
+               }
+       }
+}
+
diff --git a/Tests/Core/Drawables/TestEllipse.cs b/Tests/Core/Drawables/TestEllipse.cs
new file mode 100644
index 0000000..5404a12
--- /dev/null
+++ b/Tests/Core/Drawables/TestEllipse.cs
@@ -0,0 +1,96 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using NUnit.Framework;
+using LongoMatch.Common;
+using LongoMatch.Store.Drawables;
+
+namespace Tests.Core.Drawables
+{
+       [TestFixture()]
+       public class TestEllipse
+       {
+               [Test()]
+               public void TestSerialization ()
+               {
+                       Point c = new Point (10, 10);
+                       Ellipse e = new Ellipse (c, 3, 2);
+                       Utils.CheckSerialization (e);
+                       Ellipse ne = Utils.SerializeDeserialize (e);
+                       Assert.AreEqual (ne.Center, e.Center);
+                       Assert.AreEqual (ne.AxisX, e.AxisX);
+                       Assert.AreEqual (ne.AxisY, e.AxisY);
+               }
+               
+               [Test()]
+               public void TestAxis ()
+               {
+                       Point c = new Point (10, 10);
+                       Ellipse e = new Ellipse (c, 3, 2);
+                       Assert.AreEqual (new Point (13, 10), e.Right);
+                       Assert.AreEqual (new Point (7, 10), e.Left);
+                       Assert.AreEqual (new Point (10, 12), e.Top);
+                       Assert.AreEqual (new Point (10, 8), e.Bottom);
+               }
+               
+               [Test()]
+               public void TestMove ()
+               {
+                       Point c = new Point (10, 10);
+                       Ellipse e = new Ellipse (c, 3, 2);
+
+                       /* Move axis */
+                       Point p = new Point (8, 9);
+                       e.Move (SelectionPosition.Left, p, null);
+                       Assert.AreEqual (10, e.Center.X);
+                       Assert.AreEqual (10, e.Center.Y);
+                       Assert.AreEqual (2, e.AxisX);
+                       Assert.AreEqual (2, e.AxisY);
+                       
+                       p = new Point (15, 5);
+                       e.Move (SelectionPosition.Left, p, null);
+                       Assert.AreEqual (10, e.Center.X);
+                       Assert.AreEqual (10, e.Center.Y);
+                       Assert.AreEqual (5, e.AxisX);
+                       Assert.AreEqual (2, e.AxisY);
+                       
+                       p = new Point (15, 5);
+                       e.Move (SelectionPosition.Bottom, p, null);
+                       Assert.AreEqual (10, e.Center.X);
+                       Assert.AreEqual (10, e.Center.Y);
+                       Assert.AreEqual (5, e.AxisX);
+                       Assert.AreEqual (5, e.AxisY);
+                       
+                       p = new Point (15, 12);
+                       e.Move (SelectionPosition.Top, p, null);
+                       Assert.AreEqual (10, e.Center.X);
+                       Assert.AreEqual (10, e.Center.Y);
+                       Assert.AreEqual (5, e.AxisX);
+                       Assert.AreEqual (2, e.AxisY);
+                       
+                       /* Move all */
+                       p = new Point (15, 12);
+                       e.Move (SelectionPosition.All, p, new Point (10, 10));
+                       Assert.AreEqual (15, e.Center.X);
+                       Assert.AreEqual (12, e.Center.Y);
+                       Assert.AreEqual (5, e.AxisX);
+                       Assert.AreEqual (2, e.AxisY);
+               }
+       }
+}
+
diff --git a/Tests/Core/Drawables/TestLine.cs b/Tests/Core/Drawables/TestLine.cs
new file mode 100644
index 0000000..f649ce5
--- /dev/null
+++ b/Tests/Core/Drawables/TestLine.cs
@@ -0,0 +1,143 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using NUnit.Framework;
+using LongoMatch.Common;
+using LongoMatch.Store.Drawables;
+
+namespace Tests.Core.Drawables
+{
+       [TestFixture()]
+       public class TestLine
+       {
+               [Test()]
+               public void TestSerialization ()
+               {
+                       Point p1, p2;
+                       
+                       p1 = new Point (0, 0);
+                       p2 = new Point (5, 5);
+                       Line line = new Line (p1, p2, LineType.Arrow, LineStyle.Dashed);
+                               
+                       Utils.CheckSerialization (line);
+                       
+                       Line newLine = Utils.SerializeDeserialize (line);
+                       Assert.AreEqual (line.Start, newLine.Start);
+                       Assert.AreEqual (line.Stop, newLine.Stop);
+               }
+               
+               [Test()]
+               public void TestCenter ()
+               {
+                       Point p1, p2;
+
+                       p1 = new Point (0, 0);
+                       p2 = new Point (5, 5);
+                       Line line = new Line (p1, p2, LineType.Arrow, LineStyle.Dashed);
+                       
+                       Assert.AreEqual (new Point (2.5, 2.5), line.Center);
+               }
+               
+               [Test()]
+               public void TestGetSelection ()
+               {
+                       Point p1, p2, p3;
+                       Selection s;
+
+                       p1 = new Point (0, 5);
+                       p2 = new Point (5, 5);
+                       Line line = new Line (p1, p2, LineType.Arrow, LineStyle.Dashed);
+                       
+                       /* None */
+                       p3 = new Point (10, 5);
+                       s = line.GetSelection (p3, 1);
+                       Assert.AreEqual (SelectionPosition.None, s.Position);
+                       
+                       /* Start */
+                       p3 = new Point (0, 5);
+                       s = line.GetSelection (p3, 1);
+                       Assert.AreEqual (SelectionPosition.LineStart, s.Position);
+                       Assert.AreEqual ((double)0, s.Accuracy);
+                       p3 = new Point (1, 5);
+                       s = line.GetSelection (p3, 1);
+                       Assert.AreEqual (SelectionPosition.LineStart, s.Position);
+                       Assert.AreEqual ((double)1, s.Accuracy);
+                       
+                       /* Stop */
+                       p3 = new Point (5, 5);
+                       s = line.GetSelection (p3, 1);
+                       Assert.AreEqual (SelectionPosition.LineStop, s.Position);
+                       Assert.AreEqual ((double)0, s.Accuracy);
+                       p3 = new Point (6, 5);
+                       s = line.GetSelection (p3, 1);
+                       Assert.AreEqual (SelectionPosition.LineStop, s.Position);
+                       Assert.AreEqual ((double)1, s.Accuracy);
+                       
+                       /* All */
+                       p3 = new Point (2, 5);
+                       s = line.GetSelection (p3, 1);
+                       Assert.AreEqual (SelectionPosition.All, s.Position);
+                       Assert.AreEqual ((double)0, s.Accuracy);
+                       p3 = new Point (2, 5.1);
+                       s = line.GetSelection (p3, 1);
+                       Assert.AreEqual (SelectionPosition.All, s.Position);
+                       Assert.AreEqual (0.1, Math.Round (s.Accuracy, 3));
+                       
+                       
+                       p1 = new Point (0, 0);
+                       p2 = new Point (5, 5);
+                       line = new Line (p1, p2, LineType.Arrow, LineStyle.Dashed);
+
+                       p3 = new Point (0, 3);
+                       s = line.GetSelection (p3, 1);
+                       Assert.AreEqual (SelectionPosition.None, s.Position);
+                       
+                       p3 = new Point (2.5, 2.5);
+                       s = line.GetSelection (p3, 1);
+                       Assert.AreEqual (SelectionPosition.All, s.Position);
+                       Assert.AreEqual ((double)0, s.Accuracy);
+               }
+               
+               [Test()]
+               public void TestMove ()
+               {
+                       Point p1, p2, p3, p4;
+
+                       p1 = new Point (5, 5);
+                       p2 = new Point (7, 10);
+                       Line line = new Line (p1, p2, LineType.Arrow, LineStyle.Dashed);
+                       p3 = new Point (8, 20);
+                       line.Move (SelectionPosition.LineStart, p3, null);
+                       Assert.AreEqual (line.Start, p3);
+                       p3 = new Point (10, 10);
+                       line.Move (SelectionPosition.LineStop, p3, null);
+                       Assert.AreEqual (line.Stop, p3);
+                       
+                       line.Start = new Point (5, 5);
+                       line.Stop = new Point (7, 10);
+                       p3 = new Point (10, 10);
+                       p4 = new Point (2, 5);
+                       line.Move (SelectionPosition.All, p3, p4);
+                       Assert.AreEqual (line.Start.X, 5 + 8);
+                       Assert.AreEqual (line.Start.Y, 5 + 5);
+                       Assert.AreEqual (line.Stop.X, 7 + 8);
+                       Assert.AreEqual (line.Stop.Y, 10 + 5);
+               }
+       }
+}
+
diff --git a/Tests/Core/Drawables/TestMultipoints.cs b/Tests/Core/Drawables/TestMultipoints.cs
new file mode 100644
index 0000000..8423250
--- /dev/null
+++ b/Tests/Core/Drawables/TestMultipoints.cs
@@ -0,0 +1,103 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using System.Collections.Generic;
+using NUnit.Framework;
+using LongoMatch.Common;
+using LongoMatch.Store.Drawables;
+
+namespace Tests.Core.Drawables
+{
+       [TestFixture()]
+       public class TestMultipoints
+       {
+               [Test()]
+               public void TestSerialization ()
+               {
+                       Point p1, p2, p3;
+                       List<Point> l;
+                       
+                       p1 = new Point (2, 2);
+                       p2 = new Point (3, 5);
+                       p3 = new Point (6, 8);
+                       l = new List<Point> ();
+                       l.Add (p1);
+                       l.Add (p2);
+                       l.Add (p3);
+                       
+                       MultiPoints m = new MultiPoints (l);
+                       Utils.CheckSerialization (m);
+                       MultiPoints nm = Utils.SerializeDeserialize(m);
+                       Assert.AreEqual (p1, nm.Points[0]);
+                       Assert.AreEqual (p2, nm.Points[1]);
+                       Assert.AreEqual (p3, nm.Points[2]);
+               }
+               
+               [Test()]
+               public void TestAxis ()
+               {
+                       double xmin, xmax, ymin, ymax;
+                       Point p1, p2, p3;
+                       List<Point> l;
+                       
+                       p1 = new Point (2, 2);
+                       p2 = new Point (3, 5);
+                       p3 = new Point (6, 8);
+                       l = new List<Point> ();
+                       l.Add (p1);
+                       l.Add (p2);
+                       l.Add (p3);
+                       xmin = 2;
+                       xmax = 6;
+                       ymin = 2;
+                       ymax = 8;
+                       
+                       MultiPoints m = new MultiPoints (l);
+                       Assert.AreEqual (new Point (xmin, ymax), m.TopLeft);
+                       Assert.AreEqual (new Point (xmax, ymax), m.TopRight);
+                       Assert.AreEqual (new Point (xmax, ymin), m.BottomRight);
+                       Assert.AreEqual (new Point (xmin, ymin), m.BottomLeft);
+               }
+               
+               [Test()]
+               public void TestSelection ()
+               {
+                       Point p1, p2, p3;
+                       List<Point> l;
+                       Selection s;
+                       
+                       p1 = new Point (2, 2);
+                       p2 = new Point (3, 5);
+                       p3 = new Point (6, 8);
+                       l = new List<Point> ();
+                       l.Add (p1);
+                       l.Add (p2);
+                       l.Add (p3);
+                       
+                       MultiPoints m = new MultiPoints (l);
+                       s = m.GetSelection (new Point (3, 5), 1);
+                       Assert.AreEqual (SelectionPosition.All, s.Position);
+                       
+                       s = m.GetSelection (new Point (0, 5), 1);
+                       Assert.AreEqual (SelectionPosition.None, s.Position);
+                       s = m.GetSelection (new Point (5, 12), 1);
+                       Assert.AreEqual (SelectionPosition.None, s.Position);
+               }
+       }
+}
+
diff --git a/Tests/Core/Drawables/TestQuadrilateral.cs b/Tests/Core/Drawables/TestQuadrilateral.cs
new file mode 100644
index 0000000..97f35ed
--- /dev/null
+++ b/Tests/Core/Drawables/TestQuadrilateral.cs
@@ -0,0 +1,126 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using NUnit.Framework;
+using LongoMatch.Store.Drawables;
+using LongoMatch.Common;
+
+namespace Tests.Core.Drawables
+{
+       [TestFixture()]
+       public class TestQuadrilateral
+       {
+               [Test()]
+               public void TestSerialization ()
+               {
+                       Point tl, tr, br, bl;
+                       Quadrilateral q, nq;
+                       
+                       bl = new Point (1, 1);
+                       br = new Point (10, 4);
+                       tl = new Point (3, 20);
+                       tr = new Point (12, 15);
+                       q = new Quadrilateral (tl, tr, bl, br);
+                       Utils.CheckSerialization (q);
+                       nq = Utils.SerializeDeserialize (q);
+                       Assert.AreEqual (q.BottomLeft, nq.BottomLeft);
+                       Assert.AreEqual (q.BottomRight, nq.BottomRight);
+                       Assert.AreEqual (q.TopLeft, nq.TopLeft);
+                       Assert.AreEqual (q.TopRight, nq.TopRight);
+               }
+               
+               [Test()]
+               public void TestGetSelection ()
+               {
+                       Point tl, tr, br, bl;
+                       Quadrilateral q;
+                       Selection s;
+                       
+                       bl = new Point (1, 1);
+                       br = new Point (10, 4);
+                       tl = new Point (3, 20);
+                       tr = new Point (12, 15);
+                       q = new Quadrilateral (tl, tr, bl, br);
+                       
+                       s = q.GetSelection (bl, 1);
+                       Assert.AreEqual (SelectionPosition.BottomLeft, s.Position);
+                       s = q.GetSelection (br, 1);
+                       Assert.AreEqual (SelectionPosition.BottomRight, s.Position);
+                       s = q.GetSelection (tl, 1);
+                       Assert.AreEqual (SelectionPosition.TopLeft, s.Position);
+                       s = q.GetSelection (tr, 1);
+                       Assert.AreEqual (SelectionPosition.TopRight, s.Position);
+                       
+                       /* rectangle
+                        *  1,20   12,20
+                        *  1,1    12, 1
+                        */ 
+                       s = q.GetSelection (new Point (0, 1), 0.5);
+                       Assert.AreEqual (SelectionPosition.None, s.Position);
+                       s = q.GetSelection (new Point (1, 21), 0.5);
+                       Assert.AreEqual (SelectionPosition.None, s.Position);
+                       s = q.GetSelection (new Point (13, 5), 0.5);
+                       Assert.AreEqual (SelectionPosition.None, s.Position);
+                       s = q.GetSelection (new Point (4, 0), 0.5);
+                       Assert.AreEqual (SelectionPosition.None, s.Position);
+                       
+                       s = q.GetSelection (new Point (4, 5), 0);
+                       Assert.AreEqual (SelectionPosition.All, s.Position);
+               }
+               
+               [Test()]
+               public void TestMove ()
+               {
+                       Point tl, tr, br, bl, src, dst;
+                       Quadrilateral q;
+                       
+                       bl = new Point (1, 1);
+                       br = new Point (10, 4);
+                       tl = new Point (3, 20);
+                       tr = new Point (12, 15);
+                       q = new Quadrilateral (tl, tr, bl, br);
+                       
+                       src = new Point (4, 5);
+                       dst = new Point (7, 3);
+                       q.Move (SelectionPosition.All, dst, src);
+                       Assert.AreEqual (1 + 3, bl.X);
+                       Assert.AreEqual (10 + 3, br.X);
+                       Assert.AreEqual (3 + 3, tl.X);
+                       Assert.AreEqual (12 + 3, tr.X);
+                       
+                       Assert.AreEqual (1 - 2, bl.Y);
+                       Assert.AreEqual (4 - 2, br.Y);
+                       Assert.AreEqual (20 - 2, tl.Y);
+                       Assert.AreEqual (15 - 2, tr.Y);
+                       
+                       bl = new Point (1, 1);
+                       q.Move (SelectionPosition.BottomLeft, bl, null);
+                       Assert.AreEqual (bl, q.BottomLeft);
+                       br = new Point (10, 4);
+                       q.Move (SelectionPosition.BottomRight, br, null);
+                       Assert.AreEqual (br, q.BottomRight);
+                       tl = new Point (3, 20);
+                       q.Move (SelectionPosition.TopLeft, tl, null);
+                       Assert.AreEqual (tl, q.TopLeft);
+                       tr = new Point (12, 15);
+                       q.Move (SelectionPosition.TopRight, tr, null);
+                       Assert.AreEqual (tr, q.TopRight);
+               }
+       }
+}
+
diff --git a/Tests/Core/Drawables/TestRectangle.cs b/Tests/Core/Drawables/TestRectangle.cs
new file mode 100644
index 0000000..03d0273
--- /dev/null
+++ b/Tests/Core/Drawables/TestRectangle.cs
@@ -0,0 +1,149 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using NUnit.Framework;
+using LongoMatch.Store.Drawables;
+using LongoMatch.Common;
+
+namespace Tests.Core.Drawables
+{
+       [TestFixture()]
+       public class TestRectangle
+       {
+               [Test()]
+               public void TestSerialization ()
+               {
+                       Rectangle r, newr;
+                       
+                       r = new Rectangle (new Point (2, 10), 30, 20);
+                       Utils.CheckSerialization (r);
+                       newr = Utils.SerializeDeserialize (r);
+                       Assert.AreEqual (r.TopLeft, newr.TopLeft);
+                       Assert.AreEqual (r.TopRight, newr.TopRight);
+                       Assert.AreEqual (r.BottomLeft, newr.BottomLeft);
+                       Assert.AreEqual (r.BottomRight, newr.BottomRight);
+               }
+               
+               [Test()]
+               public void TestAxis ()
+               {
+                       Rectangle r;
+                       Point p1, p2;
+                       double width=30, height=20;
+                       
+                       p1 = new Point (2, 10);
+                       r = new Rectangle (p1, width, height);
+                       Assert.AreEqual (height, r.Height);
+                       Assert.AreEqual (width, r.Width);
+                       p2 = new Point (2, 10);
+                       Assert.AreEqual (p2, r.BottomLeft);
+                       p2.X += width; 
+                       Assert.AreEqual (p2, r.BottomRight);
+                       p2.Y += height; 
+                       Assert.AreEqual (p2, r.TopRight);
+                       p2.X = 2;
+                       Assert.AreEqual (p2, r.TopLeft);
+                       p2.X = r.BottomLeft.X + width / 2;
+                       p2.Y = r.BottomLeft.Y + height / 2;
+                       Assert.AreEqual (p2, r.Center);
+               }
+               
+               [Test()]
+               public void TestGetSelection ()
+               {
+                       Rectangle r;
+                       Point p1, p2;
+                       Selection s;
+                       double width=30, height=20;
+                       
+                       p1 = new Point (2, 10);
+                       r = new Rectangle (p1, width, height);
+                       p2 = new Point (2, 15);
+                       s = r.GetSelection (p2, 0);
+                       Assert.AreEqual (SelectionPosition.Left, s.Position);
+                       p2 = new Point (15, 30);
+                       s = r.GetSelection (p2, 0);
+                       Assert.AreEqual (SelectionPosition.Top, s.Position);
+                       p2 = new Point (32, 12);
+                       s = r.GetSelection (p2, 0);
+                       Assert.AreEqual (SelectionPosition.Right, s.Position);
+                       p2 = new Point (30, 10);
+                       s = r.GetSelection (p2, 0);
+                       Assert.AreEqual (SelectionPosition.Bottom, s.Position);
+               }
+               
+               [Test()]
+               public void TestMove ()
+               {
+                       Rectangle r1;
+                       Point p1, p2;
+                       double width=10, height=10;
+                       
+                       /* Move corners */
+                       p1 = new Point (0, 0);
+                       r1 = new Rectangle (p1, width, height);
+                       
+                       p2 = new Point (1, 1);
+                       r1.Move (SelectionPosition.BottomLeft, p2, null);
+                       CompareRect (r1, p2, 9, 9);
+                       
+                       p2 = new Point (9, 8);
+                       r1.Move (SelectionPosition.TopRight, p2, null);
+                       CompareRect (r1, new Point (1, 1), 8, 7);
+                       
+                       p2 = new Point (11, 2);
+                       r1.Move (SelectionPosition.BottomRight, p2, null);
+                       CompareRect (r1, new Point (1, 2), 10, 6);
+                       
+                       p2 = new Point (2, 9);
+                       r1.Move (SelectionPosition.TopLeft, p2, null);
+                       CompareRect (r1, new Point (2, 2), 9, 7);
+                       
+                       /* Move borders */
+                       p1 = new Point (0, 0);
+                       r1 = new Rectangle (p1, width, height);
+                       
+                       p2 = new Point (3, 5);
+                       r1.Move (SelectionPosition.Left, p2, null);
+                       CompareRect (r1, new Point (3, 0), 7, 10);
+                       
+                       p2 = new Point (5, 11);
+                       r1.Move (SelectionPosition.Top, p2, null);
+                       CompareRect (r1, new Point (3, 0), 7, 11);
+                       
+                       p2 = new Point (6, 2);
+                       r1.Move (SelectionPosition.Bottom, p2, null);
+                       CompareRect (r1, new Point (3, 2), 7, 9);
+                       
+                       p2 = new Point (8, 11);
+                       r1.Move (SelectionPosition.Right, p2, null);
+                       CompareRect (r1, new Point (3, 2), 5, 9);
+               }
+               
+               public void CompareRect (Rectangle r, Point p, double width, double height)
+               {
+                       Rectangle r2 = new Rectangle (p, width, height);
+                       Assert.AreEqual (r2.TopLeft, r.TopLeft);
+                       Assert.AreEqual (r2.TopRight, r.TopRight);
+                       Assert.AreEqual (r2.BottomLeft, r.BottomLeft);
+                       Assert.AreEqual (r2.BottomRight, r.BottomRight);
+                       
+               }
+               
+       }
+}
\ No newline at end of file
diff --git a/Tests/Core/Drawables/TestText.cs b/Tests/Core/Drawables/TestText.cs
new file mode 100644
index 0000000..c6cc172
--- /dev/null
+++ b/Tests/Core/Drawables/TestText.cs
@@ -0,0 +1,47 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using NUnit.Framework;
+using LongoMatch.Store.Drawables;
+using LongoMatch.Common;
+using Text = LongoMatch.Store.Drawables.Text;
+
+
+namespace Tests.Core.Drawables
+{
+       [TestFixture()]
+       public class TestText
+       {
+               [Test()]
+               public void TestSerialization ()
+               {
+                       Point o = new Point (10, 10);
+                       Text t = new Text (o, 10, 10, "TEST");
+                       Utils.CheckSerialization (t);
+                       Text nt = Utils.SerializeDeserialize (t);
+                       Assert.AreEqual ("TEST", nt.Value);
+                       
+                       Rectangle r = new Rectangle (o, 10, 10);
+                       Assert.AreEqual (r.TopLeft, t.TopLeft);
+                       Assert.AreEqual (r.TopRight, t.TopRight);
+                       Assert.AreEqual (r.BottomLeft, t.BottomLeft);
+                       Assert.AreEqual (r.BottomRight, t.BottomRight);
+               }
+       }
+}
+
diff --git a/Tests/Tests.mdp b/Tests/Tests.mdp
index 9c449be..899da55 100644
--- a/Tests/Tests.mdp
+++ b/Tests/Tests.mdp
@@ -34,6 +34,17 @@
     <File subtype="Directory" buildaction="Compile" name="Services" />
     <File subtype="Code" buildaction="Compile" name="Services/TestDatabase.cs" />
     <File subtype="Code" buildaction="Compile" name="Services/TestDatabasesManager.cs" />
+    <File subtype="Directory" buildaction="Compile" name="Core/Drawables" />
+    <File subtype="Code" buildaction="Compile" name="Core/Drawables/TestLine.cs" />
+    <File subtype="Code" buildaction="Compile" name="Core/Drawables/TestCross.cs" />
+    <File subtype="Code" buildaction="Compile" name="Core/Drawables/TestRectangle.cs" />
+    <File subtype="Code" buildaction="Compile" name="Core/Drawables/TestQuadrilateral.cs" />
+    <File subtype="Code" buildaction="Compile" name="Core/Drawables/TestEllipse.cs" />
+    <File subtype="Code" buildaction="Compile" name="Core/Drawables/TestText.cs" />
+    <File subtype="Code" buildaction="Compile" name="Core/Drawables/TestAngle.cs" />
+    <File subtype="Code" buildaction="Compile" name="Core/Drawables/TestMultipoints.cs" />
+    <File subtype="Code" buildaction="Compile" name="Core/Drawables/TestDrawable.cs" />
+    <File subtype="Code" buildaction="Compile" name="Core/Drawables/TestCircle.cs" />
     <File subtype="Code" buildaction="Compile" name="Core/TestColor.cs" />
   </Contents>
   <References>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]