//---------------------------------------------------------------------------

#include <vcl.h>
#include <math.h>
#include <stdlib.h>
#pragma hdrstop

#include "APErrorSeries.h"
//---------------------------------------------------------------------------

__fastcall TErrPointSeries::~TErrPointSeries() {

        if (FErrorPen) delete FErrorPen;
        //if (FErrorValues)
        //delete FErrorValues;
        //TPointSeries::~TPointSeries();
        }

__fastcall  TErrPointSeries::TErrPointSeries(TComponent* Owner,AnsiString name,TColor pcolour) : TPointSeries(Owner){
   StaticColour = pcolour;
   FErrorValues = 0;
   FErrorValues = new TChartValueList(this,"");
   FErrorPen = CreateChartPen();
   FErrorPen->Color = pcolour;
   FErrorStyle = essTopBottom;
   FErrorWidth=300;
   FErrorWidthUnits=ewuPercent;
   Marks->Visible=false;
   Pointer->VertSize =1;
   Pointer->HorizSize =1;
   Pointer->Pen->Color = pcolour;
   Pointer->Brush->Color = pcolour;

   percentage = 0;
   fixed = 0;
}

void __fastcall TErrPointSeries::staticcolourw(TColor s){
StaticColour = s;
FErrorPen->Color = s;
Pointer->Brush->Color = s;
Pointer->Pen->Color = s;
}
void __fastcall TErrPointSeries::fixedw(double f){ fixed=f; ftype = 1;}
void __fastcall TErrPointSeries::percentagew(double p){ percentage = p ; ftype = 0; }

double TErrPointSeries::GetErrorValue(long int Index) {return FErrorValues->Value[Index];}

void __fastcall TErrPointSeries::SetErrorValue(long int Index, double const Value) {FErrorValues->Value[Index] = Value;}

AnsiString __fastcall TErrPointSeries::GetEditorClass() {return "TErrorSeriesEditor";}

void __fastcall TErrPointSeries::PrepareErrorPen(int ValueIndex){
 ParentChart->Canvas->AssignVisiblePen(FErrorPen);
    if (ValueIndex==TeeAllValues) {
       ParentChart->Canvas->Pen->Color=ValueColor[ValueIndex];
    ParentChart->Canvas->BackMode=cbmTransparent;   }
}
void __fastcall TErrPointSeries::SetErrorStyle(TErrorSeriesStyle Value){
if (FErrorStyle != Value) { FErrorStyle=Value;  Repaint(); } }
void __fastcall TErrPointSeries::SetErrorValues(TChartValueList *Value){SetChartValueList(FErrorValues,Value); }
void __fastcall TErrPointSeries::SetErrorWidthUnits(TErrorWidthUnits Value){
        if (FErrorWidthUnits != Value) { FErrorWidthUnits = Value; Repaint();       }    }
void __fastcall TErrPointSeries::SetErrorPen(TChartPen *Value){ FErrorPen->Assign(Value);  SeriesColor=FErrorPen->Color; }
void __fastcall TErrPointSeries::SetErrorWidth(long int Value){ SetIntegerProperty(FErrorWidth,Value); }
void TErrPointSeries::DrawError(int long X, int long Y, int long AWidth,int long AHeight, bool Draw3D){
        switch (FErrorStyle) {
                case essLeft  : {DrawHoriz(X+AHeight, X,  Y,  AWidth, AHeight,  Draw3D);
                        break; }
                case essRight    : { DrawHoriz(X-AHeight, X,  Y,  AWidth, AHeight,  Draw3D);
                        break; }
                case essLeftRight: {
                    DrawHoriz(X+AHeight, X,  Y,  AWidth, AHeight,  Draw3D);
                    DrawHoriz(X-AHeight, X,  Y,  AWidth, AHeight,  Draw3D);
                        break;
                  }
                case essTop      : {DrawVert(Y-AHeight, X,  Y,  AWidth, AHeight,  Draw3D);
                        break; }
                case essBottom   : {DrawVert(Y+AHeight, X,  Y,  AWidth, AHeight,  Draw3D);
                        break; }
                case essTopBottom: {
                    DrawVert(Y-AHeight, X,  Y,  AWidth, AHeight,  Draw3D);
                    DrawVert(Y+AHeight, X,  Y,  AWidth, AHeight,  Draw3D);
                        break; }                  }     }
void TErrPointSeries::DrawHoriz(int long XPos,int long X, int long Y, int long AWidth,int long AHeight, bool Draw3D) {
        while (ParentChart->Canvas) {
        if (Draw3D) {
                ParentChart->Canvas->HorizLine3D(X,XPos,Y,MiddleZ);
                ParentChart->Canvas->VertLine3D(XPos,Y-AHeight,Y+AHeight,MiddleZ);
        }else{
                ParentChart->Canvas->DoHorizLine(X,XPos,Y);
                ParentChart->Canvas->DoVertLine(XPos,(Y-AWidth / 2),Y+(AWidth / 2));
      }      }   }
void TErrPointSeries::DrawVert(int long YPos,int long X, int long Y, int long AWidth,int long AHeight, bool Draw3D){
if (ParentChart->Canvas) {
        if (Draw3D) {
                ParentChart->Canvas->VertLine3D(X,Y,YPos,MiddleZ);
                ParentChart->Canvas->HorizLine3D(X-(AWidth / 2),X+(AWidth / 2),YPos,MiddleZ);
        }else{
                ParentChart->Canvas->DoVertLine(X,Y,YPos);
                ParentChart->Canvas->DoHorizLine(X-(AWidth / 2),X+(AWidth / 2),YPos);
        }         }    }


void __fastcall TErrPointSeries::SetSeriesColor(TColor *AColor){
        TPointSeries:SetSeriesColor(AColor); FErrorPen->Color = *AColor;}
void __fastcall  TErrPointSeries::DrawValue(int ValueIndex){
        long int tmpX, tmpY, tmp, tmpWidth, ErrorTop; double tmpError;
        TPointSeries::DrawValue(ValueIndex);
        if (FErrorPen->Visible) {
       tmpError=FErrorValues->Value[ValueIndex];
       if (tmpError!=0)
         ErrorTop=0;
         tmpX=CalcXPosValue(XValue[ValueIndex]);
         tmpY=CalcYPosValue(YValue[ValueIndex]);
         if ((FErrorStyle == essTop) || (FErrorStyle == essBottom) || (FErrorStyle == essTopBottom) ) {
               ErrorTop=CalcYPosValue(YValue[ValueIndex]+tmpError);
               tmp=tmpY;
               tmpWidth=Pointer->VertSize;
              }else {
               ErrorTop=CalcXPosValue(XValue[ValueIndex]+tmpError);
               tmp=tmpX;
               tmpWidth=Pointer->HorizSize;
          }
            if (FErrorWidthUnits==ewuPercent) {
         tmpWidth=floor(1.0*FErrorWidth*tmpWidth/100.0);
         }else {tmpWidth=FErrorWidth;
         tmpWidth = this->Pointer->VertSize * 20;
         //tmpWidth=floor(1.0*FErrorWidth*tmpWidth/100.0);
         }
      this->Pointer->VertSize;
      PrepareErrorPen(ValueIndex);
      DrawError(tmpX,tmpY,
                 tmpWidth,(tmp-ErrorTop),ParentChart->View3D);   }
                   }
long int TErrPointSeries::AddErrorPoint(const double AX,const double AY, const double AError, const AnsiString AXLabel, TColor AColor){
        double error;
        if (AError == -1) {
                if (ftype) { error= fixed;
                }else{ error = AY * percentage /100; }
        }else {error = AError;}
        int r=AddXY(AX,AY,AXLabel,AColor); //{ standard add X,Y }
        FErrorValues->TempValue=error;
        AddValue(r);
        return r;
        }


void __fastcall TErrPointSeries::CalcHorizMargins(int LeftMargin, int RightMargin){
  TPointSeries:CalcHorizMargins(LeftMargin,RightMargin);
  if ((FErrorStyle==essLeft) || (FErrorStyle==essLeftRight)) {
     LeftMargin  =MaxLong(LeftMargin, FErrorPen->Width);    }
  if ((FErrorStyle==essRight) || (FErrorStyle==essLeftRight)) {
     RightMargin =MaxLong(RightMargin, FErrorPen->Width);     }


}
void __fastcall TErrPointSeries::CalcVerticalMargins(long int TopMargin, long int BottomMargin){

  TPointSeries:CalcVerticalMargins(TopMargin,BottomMargin);
  if ((FErrorStyle==essTop) || (FErrorStyle==essTopBottom)) {
     TopMargin    =MaxLong(TopMargin, FErrorPen->Width);  }
  if ((FErrorStyle==essBottom) || (FErrorStyle==essTopBottom)) {
     BottomMargin =MaxLong(BottomMargin, FErrorPen->Width); }

}
void __fastcall TErrPointSeries::DrawLegendShape(long int ValueIndex, const TRect *Rect){
        int tmp;
        PrepareErrorPen(ValueIndex);
                switch (FErrorStyle) {
                case essTop  : { tmp = Rect->Bottom-Rect->Top;  break;}
                case essBottom : { tmp = Rect->Bottom-Rect->Top;  break;}
                case essTopBottom  : { tmp = Rect->Bottom-Rect->Top;  break;}
                default : { tmp=Rect->Top-Rect->Bottom; break ;  }
                }
                DrawError ((Rect->Left+Rect->Right) , (Rect->Top+Rect->Bottom) , (Rect->Right-Rect->Left),tmp / 2,false);
        }
void __fastcall TErrPointSeries::FillSampleValues(long int NumValues){ //overide; { <-- to add random error values }
long int t; double tmpX,tmpY,StepX,MinY,DifY;  Clear(); CalcRandomBounds(NumValues,tmpX,StepX,tmpY,MinY,DifY);
        for (t=1;t <= NumValues ; t++) {// ome sample values to see something in design mode }
    AddErrorPoint( tmpX,   random(floor(DifY)), DifY/(20+random(4)),"", clTeeColor);
    tmpX=tmpX+StepX; }   RefreshSeries();  }
double __fastcall TErrPointSeries::MinYValue(){
  double r = TPointSeries::MaxYValue();
  double i = TPointSeries::MinYValue();
  if (!FErrorValues) return i;
  for (long int t=0; t<Count();t++) {
        if (r < YValue[t]+FErrorValues->Value[t]) {r = YValue[t]+FErrorValues->Value[t]; }
        if (i > YValue[t]-FErrorValues->Value[t]) {i = YValue[t]-FErrorValues->Value[t]; }
         }
  return i - (r-i)*0.02;
} // override;
double __fastcall TErrPointSeries::MaxYValue(){

double r = TPointSeries::MaxYValue();
double i = TPointSeries::MinYValue();
  if (!FErrorValues) return r;
  for (long int t=0; t<Count();t++) {
        if (r < YValue[t]+FErrorValues->Value[t]) {r = YValue[t]+FErrorValues->Value[t]; }
        if (i > YValue[t]-FErrorValues->Value[t]) {i = YValue[t]-FErrorValues->Value[t]; }
         }
  return r + (r-i)*0.02;
} // override;


double __fastcall TErrPointSeries::MinXValue(){
    double x = TPointSeries::MaxXValue();
    double i = TPointSeries::MinXValue();
    return  i - (x-i)*0.02;
} // override;
double __fastcall TErrPointSeries::MaxXValue(){
    double x = TPointSeries::MaxXValue();
    double i = TPointSeries::MinXValue();
    return  x + (x-i)*0.02;
} // override;

void __fastcall TErrPointSeries::Assign(TPersistent *Source){   // dont really need
  TPointSeries:Assign(Source);
} //override;
void __fastcall TErrPointSeries::PrepareForGallery(bool IsEnabled){
        TPointSeries::PrepareForGallery(IsEnabled);
        //ParentChart->Canvas
        //  FErrorPen->Color=ParentChart->ErrorColors[IsEnabled];
        //  SeriesColor=Colors[IsEnabled];
} //override;

//---------------------------------------------------------------------------


