/* ======================================================================== *\
!
! *
! * This file is part of MARS, the MAGIC Analysis and Reconstruction
! * Software. It is distributed to you in the hope that it can be a useful
! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
! * It is distributed WITHOUT ANY WARRANTY.
! *
! * Permission to use, copy, modify and distribute this software and its
! * documentation for any purpose is hereby granted without fee,
! * provided that the above copyright notice appear in all copies and
! * that both that copyright notice and this permission notice appear
! * in supporting documentation. It is provided "as is" without express
! * or implied warranty.
! *
!
!
!   Author(s): Harald Kornmayer 1/2001 (harald@mppmu.mpg.de)
!   Author(s): Thomas Bretz  12/2000 (tbretz@uni-sw.gwdg.de)
!
!   Copyright: MAGIC Software Development, 2000-2001
!
!
\* ======================================================================== */

//
//  The class MHexagon is needed for the Event Display of
//  MAGIC.
//
#include "MHexagon.h"

#include <TVirtualPad.h>  // gPad

#include "MGeomPix.h"     // GetX

ClassImp(MHexagon) 

MHexagon::MHexagon() 
{
  //   default constructor for MHexagon 

} 

MHexagon::MHexagon(Float_t x, Float_t y, Float_t d )
 : TAttFill(0, 1001), fX(x), fY(y), fD(d)
{ 
  //    normal constructor for MHexagon
}

MHexagon::MHexagon(MGeomPix &pix)
 : TAttFill(0, 1001)
{
  //    normal constructor for MHexagon
   fX = pix.GetX();
   fY = pix.GetY();
   fD = pix.GetR();
}

MHexagon::MHexagon( const MHexagon &hexagon)
{
  //    copy constructor for MHexagon 
  ((MHexagon&) hexagon).Copy(*this) ; 
} 

MHexagon::~MHexagon()
{ 
  //     default destructor for MHexagon
}  

void MHexagon::Copy( TObject &obj ) 
{ 
    //     copy this hexagon to hexagon
    MHexagon &hex = (MHexagon&) obj;

    TObject::Copy(obj);
    TAttLine::Copy(hex);
    TAttFill::Copy(hex);

    hex.fX = fX ;
    hex.fY = fY ;
    hex.fD = fD ;
}
Int_t MHexagon::DistancetoPrimitive( Int_t px, Int_t py )
{
    //   compute the distance of a point (px,py) to the Hexagon
    //   this functions needed for graphical primitives, that
    //   means without this function you are not able to interact
    //   with the graphical primitive with the mouse!!!
    //
    //   All calcutations are running in pixel coordinates

    //       compute the distance of the Point to the center of the Hexagon

  const Int_t  pxhex = gPad->XtoAbsPixel( fX ) ;
  const Int_t  pyhex = gPad->YtoAbsPixel( fY ) ; 

  const Double_t DistPointHexagon = TMath::Sqrt( Double_t ((pxhex-px)*(pxhex-px) + (pyhex-py)*(pyhex-py))) ; 
  const Double_t cosa = TMath::Abs(px-pxhex) / DistPointHexagon ; 
  const Double_t sina = TMath::Abs(py-pyhex) / DistPointHexagon ; 

  //       comput the distance to pixel border 
  
  const Double_t   dx = fD * cosa / 2 ; 
  const Double_t   dy = fD * sina / 2 ; 
  
  const Double_t   xborder = fX + dx ; 
  const Double_t   yborder = fY + dy ; 

  const Int_t  pxborder = gPad->XtoAbsPixel( xborder ) ; 
  const Int_t  pyborder = gPad->YtoAbsPixel( yborder ) ; 
  
  const Double_t DistBorderHexagon = TMath::Sqrt( Double_t ((pxborder-pxhex)*(pxborder-pxhex)+(pyborder-pyhex)*(pyborder-pyhex))) ;  
  
 
  //       compute the distance from the border of Pixel  
  //       here in the first implementation is just circle inside

  return DistBorderHexagon <  DistPointHexagon ? 999999 : 0;
} 

void MHexagon::DrawHexagon( Float_t x, Float_t y, Float_t d )
{ 
  //   Draw this ellipse with new coordinate
  
  MHexagon *newhexagon = new MHexagon(x, y, d ) ; 
  TAttLine::Copy(*newhexagon) ; 
  TAttFill::Copy(*newhexagon) ; 

  newhexagon->SetBit (kCanDelete) ; 
  newhexagon->AppendPad() ; 
} 

void MHexagon::ExecuteEvent(Int_t event, Int_t px, Int_t py ) { 
  //    This is the first test of implementing a clickable interface
  //    for one pixel

  switch ( event ) { 

  case kButton1Down: 
    
    printf ("\n kButton1Down \n" ) ; 
    SetFillColor(2) ;
    gPad->Modified() ; 
    break;     

  case kButton1Double: 
    SetFillColor(0) ;
    gPad->Modified() ; 
    break;     
    //  case kMouseEnter:  
    //     printf ("\n Mouse inside object \n" ) ; 
    //     break; 
  } 

} 



void MHexagon::ls( Option_t *)
{
  //     list this hexagon with its attributes
  TROOT::IndentLevel() ; 
  printf ("%s:  X= %f  Y= %f R= %f \n", GetName(), fX, fY, fD ) ;
} 

void MHexagon::Paint(Option_t * ) 
{
  //     paint this hexagon with its attribute

  PaintHexagon(fX, fY, fD ) ; 
} 


void MHexagon::PaintHexagon (Float_t inX, Float_t inY, Float_t inD ) 
{ 
  //      draw this hexagon with the coordinates

  const Int_t np =  6 ; 
  
  const Float_t dx[np+1] = { .5   , 0.    , -.5   , -.5   , 0.    ,  .5   , .5    } ;
  const Float_t dy[np+1] = { .2886,  .5772,  .2886, -.2886, -.5772, -.2886, .2886 } ;

  static Float_t x[np+1], y[np+1] ; 
  
  TAttLine::Modify() ;    // Change line attributes only if neccessary
  TAttFill::Modify() ;    // Change fill attributes only if neccessary
    
  //  calculate the positions of the pixel corners

  for ( Int_t i=0; i<=np; i++ ) { 
    x[i] = inX + dx[i]* inD ; 
    y[i] = inY + dy[i]* inD ; 
  } 

  //   paint the pixel (hopefully) 
  
  if ( GetFillColor() ) gPad->PaintFillArea(np, x, y) ; 
  if ( GetLineStyle() ) gPad->PaintPolyLine(np+1, x, y) ; 
  
} 

void MHexagon::Print( Option_t * )
{
  //     print/dump this hexagon with its attributes
  printf ("Ellipse:  X= %f  Y= %f R= %f ", fX, fY, fD ) ;
  
  if ( GetLineColor() != 1 ) printf (" Color=%d", GetLineColor() ) ; 
  if ( GetLineStyle() != 1 ) printf (" Color=%d", GetLineStyle() ) ; 
  if ( GetLineWidth() != 1 ) printf (" Color=%d", GetLineWidth() ) ;

  if ( GetFillColor() != 0 ) printf (" FillColor=%d", GetFillColor() ) ; 

  printf ("\n") ; 
} 






