// File:	V3d_ColorScale.cxx
// Created:	Tue Jun 22 17:44:25 2004
// Author:	STV
//Copyright:	Open Cascade 2004

#include <V3d_ColorScale.ixx>

#include <V3d_View.hxx>

#include <Visual3d_View.hxx>
#include <Visual3d_Layer.hxx>
#include <Visual3d_ViewManager.hxx>

#include <Aspect_Window.hxx>
#include <Aspect_ColorMap.hxx>
#include <Aspect_ColorMapEntry.hxx>
#include <Aspect_SequenceOfColor.hxx>
#include <Aspect_TypeOfColorScaleData.hxx>
#include <Aspect_TypeOfColorScalePosition.hxx>

#include <TCollection_AsciiString.hxx>
#include <TCollection_ExtendedString.hxx>
#include <TColStd_SequenceOfExtendedString.hxx>

V3d_ColorScale::V3d_ColorScale( const Handle(V3d_View)& aView )
: Aspect_ColorScale(),
myView( aView ),
myDisplay( Standard_False )
{
}

Handle(V3d_View) V3d_ColorScale::View() const
{
  return myView;
}

void V3d_ColorScale::Display()
{
  myDisplay = Standard_True;
  UpdateColorScale();
}

void V3d_ColorScale::Erase()
{
  Handle(Visual3d_Layer) theOverlay = Overlay();
  if ( theOverlay.IsNull() )
    return;

  theOverlay->Clear();
  myDisplay = Standard_False;
}

Standard_Boolean V3d_ColorScale::IsDisplayed() const
{
  return myDisplay;
}

void V3d_ColorScale::Resized()
{
  if ( View().IsNull() )
    return;

  Standard_Integer aW( 0 ), aH( 0 );
  Handle(Aspect_Window) theWin = View()->Window();
  if ( !theWin.IsNull() ) {
    theWin->Size( aW, aH );
    Handle(Visual3d_Layer) theLayer = Overlay();
    if ( !theLayer.IsNull() ) {
      theLayer->Clear();
      theLayer->SetViewport( aW, aH );
    }
    UpdateColorScale();
  }
}

void V3d_ColorScale::UpdateColorScale()
{
  if ( !IsDisplayed() || View().IsNull() )
    return;

  DrawScale();
}

Standard_Boolean V3d_ColorScale::BeginPaint()
{
  if ( !Aspect_ColorScale::BeginPaint() )
    return Standard_False;

  Handle(Visual3d_Layer) theOverlay = Overlay();
  if ( theOverlay.IsNull() )
    return Standard_False;

  Standard_Integer aW( 0 ), aH( 0 );
  Handle(Aspect_Window) theWin = View()->Window();
  if ( !theWin.IsNull() )
    theWin->Size( aW, aH );

  theOverlay->Clear();
  theOverlay->Begin();
  theOverlay->SetTextAttributes( Graphic3d_NOF_ASCII_MONO, Aspect_TODT_SUBTITLE, Quantity_Color() );
  theOverlay->SetOrtho( 0, Max( aW, aH ), Max( aW, aH ), 0, Aspect_TOC_TOP_LEFT );

  return Standard_True;
}

Standard_Boolean V3d_ColorScale::EndPaint()
{
  if ( !Aspect_ColorScale::EndPaint() )
    return Standard_False;

  Handle(Visual3d_Layer) theOverlay = Overlay();
  if ( theOverlay.IsNull() )
    return Standard_False;

  theOverlay->End();

  if ( !View().IsNull() )
    View()->Redraw();

  return Standard_True;
}

void V3d_ColorScale::PaintRect( const Standard_Integer X, const Standard_Integer Y,
                                const Standard_Integer W, const Standard_Integer H,
                                const Quantity_Color& aColor, const Standard_Boolean aFilled )
{
  Handle(Visual3d_Layer) theLayer = Overlay();
  if ( theLayer.IsNull() )
    return;

  theLayer->SetColor( aColor );
  if ( aFilled )
    theLayer->DrawRectangle( X, Y, W, H );
  else {
    theLayer->SetLineAttributes( Aspect_TOL_SOLID, 0.5 );
    theLayer->BeginPolyline();
    theLayer->AddVertex( X, Y, Standard_False );
    theLayer->AddVertex( X, Y + H, Standard_True );
    theLayer->AddVertex( X + W, Y + H, Standard_True );
    theLayer->AddVertex( X + W, Y, Standard_True );
    theLayer->AddVertex( X, Y, Standard_True );
    theLayer->ClosePrimitive();
  }
}

void V3d_ColorScale::PaintText( const TCollection_ExtendedString& aText,
                                const Standard_Integer X, const Standard_Integer Y,
                                const Quantity_Color& aColor )
{
  Handle(Visual3d_Layer) theLayer = Overlay();
  if ( theLayer.IsNull() )
    return;

  theLayer->SetColor( aColor );
  theLayer->SetTextAttributes( Graphic3d_NOF_ASCII_MONO, Aspect_TODT_SUBTITLE, aColor );
  TCollection_AsciiString theText( aText.ToExtString(), '?' );
  Standard_Integer aTextH = GetTextHeight();
  Standard_Integer aWidth, anAscent, aDescent;
  TextSize(aText, aTextH, aWidth, anAscent, aDescent);
//  Standard_Integer anAscent = 3 * aTextH / 4;
  theLayer->DrawText( theText.ToCString(), X, Y + anAscent, aTextH);
//  theLayer->DrawText( theText.ToCString(), X, Y, aTextH );
}

Standard_Integer V3d_ColorScale::TextWidth( const TCollection_ExtendedString& aText ) const
{
  Standard_Integer aWidth, anAscent, aDescent;
  TextSize(aText, GetTextHeight(), aWidth, anAscent, aDescent);
//  return 5 * aText.Length();
  return aWidth;
}

Standard_Integer V3d_ColorScale::TextHeight( const TCollection_ExtendedString& aText ) const
{
  Standard_Integer aWidth, anAscent, aDescent;
//  static Standard_Integer TextHeight = 10;
//  return TextHeight;
  TextSize(aText, GetTextHeight(), aWidth, anAscent, aDescent);
  return anAscent+aDescent;
}

void V3d_ColorScale::TextSize (const TCollection_ExtendedString& AText,  const Standard_Integer AHeight, Standard_Integer& AWidth, Standard_Integer& AnAscent, Standard_Integer& ADescent) const 
{
  Standard_Real aWidth, anAscent, aDescent;
  TCollection_AsciiString theText( AText.ToExtString(), '?' );
  Handle(Visual3d_Layer) theLayer = Overlay();
  if ( !theLayer.IsNull() ) {
    theLayer->TextSize(theText.ToCString(),AHeight,aWidth,anAscent,aDescent);
    AWidth = aWidth;
    AnAscent = anAscent;
    ADescent = aDescent;
  } 
  else {
    AWidth=AnAscent=ADescent=0;
  }
}

void V3d_ColorScale::DrawScale()
{
  if ( View().IsNull() )
    return;

  Standard_Integer WinWidth( 0 ), WinHeight( 0 );
  Handle(Aspect_Window) theWin = View()->Window();
  if ( !theWin.IsNull() )
    theWin->Size( WinWidth, WinHeight );

  Standard_Integer X = GetXPosition() * WinWidth;
  Standard_Integer Y = GetYPosition() * WinHeight;

  Standard_Integer W = GetWidth() * WinWidth;
  Standard_Integer H = GetHeight() * WinHeight;

  Aspect_ColorScale::DrawScale( View()->BackgroundColor(), X, Y, W, H );
}

Handle(Visual3d_Layer) V3d_ColorScale::Overlay() const
{
  if ( myOverlay.IsNull() ) {
    if ( !View().IsNull() ) {
      Handle(Visual3d_View) theView = View()->View();
      if ( !theView.IsNull() ) {
	Handle(Visual3d_ViewManager) theViewMgr = theView->ViewManager();
	if ( !theViewMgr.IsNull() ) {
	  V3d_ColorScale* that = (V3d_ColorScale*)this;
	  that->myOverlay = new Visual3d_Layer( theViewMgr, Aspect_TOL_OVERLAY, Standard_False );
	}
      }
    }
  }
  return myOverlay;
}



