using System;
using System .Collections .Generic;
using System .Drawing;
using System .Drawing .Drawing2D;
using System .Windows .Forms;
using System .IO;
using Microsoft .Win32;
using MoveGraphLibrary;
namespace UserDrivenApplications
{
public class DotsOnPlot : GraphicalObject
{
//int version = 606;
MSPlot plot;
List<Point> pts = new List<Point> ();
List<double> args = new List<double> ();
List<double> vals = new List<double> ();
bool bShowLine = true;
int halfsize = 3; // can be from [2, 12]
//int minSensitivity = 3;
int minHalfsize = 2;
int maxHalfsize = 12;
// -------------------------------------------------
// points must go from left to right
//
public DotsOnPlot (MSPlot plotParent, Point [] points)
{
plot = plotParent;
if (points != null)
{
pts .Add (points [0]);
for (int i = 1; i < points .Length; i++)
{
pts .Add (new Point (Math .Max (pts [i - 1] .X, points [i] .X), points [i] .Y));
}
}
for (int i = 0; i < pts .Count; i++)
{
args .Add (plot .CoorToArg (pts [i] .X));
vals .Add (plot .CoorToVal (pts [i] .Y));
}
}
// -------------------------------------------------
// xs[] must go from left to right, regardless of the border values (increasing or decreasing from left to right)
//
public DotsOnPlot (MSPlot plotParent, double [] fx, double [] fy)
{
plot = plotParent;
if (fx != null && fy != null)
{
int nDots = Math .Min (fx .Length, fy .Length);
double x = fx [0];
double y = fy [0];
pts .Add (plot .PhysToPoint (x, y));
args .Add (x);
vals .Add (y);
for (int i = 1; i < nDots; i++)
{
x = Math .Max (args [i - 1], fx [i]);
y = fy [i];
pts .Add (plot .PhysToPoint (x, y));
args .Add (x);
vals .Add (y);
}
}
}
// -------------------------------------------------
// xs[] must go from left to right, regardless of the border values (increasing or decreasing from left to right)
//
public DotsOnPlot (MSPlot plotParent, List<Data_ABPair> Pairs)
{
plot = plotParent;
if (Pairs != null && Pairs .Count > 0)
{
int nDots = Pairs .Count;
double x = Pairs [0] .A_value;
double y = Pairs [0] .B_value;
double xNew;
pts .Add (plot .PhysToPoint (x, y));
args .Add (x);
vals .Add (y);
for (int i = 1; i < nDots; i++)
{
xNew = Math .Max (x, Pairs [i] .A_value);
x = xNew;
y = Pairs [i] .B_value;
pts .Add (plot .PhysToPoint (x, y));
args .Add (x);
vals .Add (y);
}
}
}
// ------------------------------------------------- indexer
public PointF this [int index]
{
get { return (pts [Math .Min (Math .Max (0, index), pts .Count - 1)]); }
}
// ------------------------------------------------- Pairs
public List<Data_ABPair> Pairs
{
set
{
if (value != null && value .Count > 0)
{
pts .Clear ();
args .Clear ();
vals .Clear ();
int nDots = value .Count;
double x = value [0] .A_value;
double y = value [0] .B_value;
double xNew;
pts .Add (plot .PhysToPoint (x, y));
args .Add (x);
vals .Add (y);
for (int i = 1; i < nDots; i++)
{
xNew = Math .Max (x, value [i] .A_value);
x = xNew;
y = value [i] .B_value;
pts .Add (plot .PhysToPoint (x, y));
args .Add (x);
vals .Add (y);
}
}
DefineCover ();
}
}
// ------------------------------------------------- DotNumber
public int DotNumber
{
get { return (pts .Count); }
}
// ------------------------------------------------- Points
public List<Point> Points
{
get { return (pts); }
}
// ------------------------------------------------- Args
public List<double> Args
{
get { return (args); }
}
// ------------------------------------------------- Vals
public List<double> Vals
{
get { return (vals); }
}
// ------------------------------------------------- PlotChanged
public void PlotChanged ()
{
for (int i = 0; i < args .Count; i++)
{
pts [i] = plot .PhysToPoint (args [i], vals [i]);
}
DefineCover ();
}
// ------------------------------------------------- HalfSize
public int HalfSize
{
get { return (halfsize); }
set
{
halfsize = Math .Min (Math .Max (minHalfsize, value), maxHalfsize);
DefineCover ();
}
}
// ------------------------------------------------- InsertNewDot
public void InsertNewDot (int iPoint, Point pt)
{
if (0 <= iPoint && iPoint <= pts .Count)
{
pts .Insert (iPoint, pt);
args .Insert (iPoint, plot .CoorToArg (pt .X));
vals .Insert (iPoint, plot .CoorToVal (pt .Y));
DefineCover ();
}
}
// ------------------------------------------------- InsertNewDotInXOrder
public int InsertNewDotInXOrder (Point pt)
{
int iPoint;
for (iPoint = 0; iPoint < pts .Count; iPoint++)
{
if (pt .X <= pts [iPoint] .X)
{
break;
}
}
InsertNewDot (iPoint, pt);
return (iPoint);
}
// ------------------------------------------------- RemoveDot
public void RemoveDot (int i)
{
if (0 <= i && i < pts .Count)
{
pts .RemoveAt (i);
args .RemoveAt (i);
vals .RemoveAt (i);
DefineCover ();
}
}
// ------------------------------------------------- Clear
public void Clear ()
{
pts .Clear ();
args .Clear ();
vals .Clear ();
DefineCover ();
}
// ------------------------------------------------- InsideDot
public int InsideDot (Point pt)
{
int iNode = -1;
MovementFreedom movements = MovementFreedom .Any;
Cursor cursor = Cursors .Default;
bool bInside = cover .Inside (pt, ref iNode, ref movements, ref cursor);
if (0 <= iNode && iNode < pts .Count)
{
return (iNode);
}
else
{
return (-1);
}
}
// ------------------------------------------------- Draw
public void Draw (Graphics grfx, MarkedLine line)
{
ValuesOnBorders bordervalues = plot .ValuesOnBorders;
Auxi_Drawing .XYcurve (grfx, plot .MainArea .Area, line,
bordervalues .Left, bordervalues .Right, bordervalues .Top, bordervalues .Bottom, args, vals, DotNumber,
SegmentLocation .Anywhere);
}
// ------------------------------------------------- DefineCover
// nodes around - .Transaparent (funny !!!)
// nodes on dots - to move them
// nodes on segments - to give information (via cursor shape) that they can be clicked to add the new dot; these nodes are not moveable !!!
public override void DefineCover ()
{
int nNodes = 4 + pts .Count;
if (bShowLine && pts .Count > 1)
{
nNodes += pts .Count - 1;
}
CoverNode [] nodes = new CoverNode [nNodes];
Rectangle rc = plot .MainArea .Area;
int wLeft = Math .Max (rc .Left, 10);
int wRight = 4000 - rc .Right;
int hTop = Math .Max (rc .Top, 10);
int hBtm = 4000 - rc .Bottom;
nodes [0] = new CoverNode (0, new Rectangle (rc .Left - wLeft, rc .Top - hTop, wLeft, hTop + rc .Height + hBtm),
MovementFreedom .Transparent, Cursors .Default);
nodes [1] = new CoverNode (1, new Rectangle (rc .Right, rc .Top - hTop, wRight, hTop + rc .Height + hBtm),
MovementFreedom .Transparent, Cursors .Default);
nodes [2] = new CoverNode (2, new Rectangle (rc .Left - wLeft, rc .Top - hTop, wLeft + rc .Width + wRight, hTop),
MovementFreedom .Transparent, Cursors .Default);
nodes [3] = new CoverNode (3, new Rectangle (rc .Left - wLeft, rc .Bottom, wLeft + rc .Width + wRight, hBtm),
MovementFreedom .Transparent, Cursors .Default);
for (int i = 0; i < pts .Count; i++)
{
nodes [4 + i] = new CoverNode (4 + i, pts [i], halfsize, Cursors .Hand);
}
if (bShowLine && pts .Count > 1)
{
int j0 = 4 + pts .Count;
for (int i = 0; i < pts .Count - 1; i++)
{
nodes [j0 + i] = new CoverNode (j0 + i, pts [i], pts [i + 1], MovementFreedom .Freeze, Cursors .Hand); // .None
}
}
cover = new Cover (nodes);
}
// -------------------------------------------------
public override void Move (int dx, int dy)
{
PlotChanged ();
}
// ------------------------------------------------- MoveNode
public override bool MoveNode (int i, int dx, int dy, Point ptM, MouseButtons catcher)
{
bool bRet = false;
if (catcher == MouseButtons .Left)
{
int j0_node = 4;
int jLast_node = j0_node + pts .Count - 1;
int k_point = i - j0_node;
int cxNew = pts [k_point] .X + dx;
if (j0_node < jLast_node)
{
if (i == j0_node)
{
if (cxNew <= pts [k_point + 1] .X)
{
bRet = true;
}
}
else if (i == jLast_node)
{
if (pts [k_point - 1] .X <= cxNew)
{
bRet = true;
}
}
else
{ // intermediate nodes
if (pts [k_point - 1] .X <= cxNew && cxNew <= pts [k_point + 1] .X)
{
bRet = true;
}
}
}
else
{ // single point !!!
bRet = true;
}
if (bRet == true)
{
SubstituteDot (k_point, new Point (cxNew, pts [k_point] .Y + dy));
}
}
return (bRet);
}
// ------------------------------------------------- SubstituteDot
private void SubstituteDot (int i, Point pt)
{
pts .RemoveAt (i);
args .RemoveAt (i);
vals .RemoveAt (i);
pts .Insert (i, pt);
args .Insert (i, plot .CoorToArg (pt .X));
vals .Insert (i, plot .CoorToVal (pt .Y));
}
}
}