// Created by: CKY / Contract Toubro-Larsen
// Copyright (c) 1993-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.

//--------------------------------------------------------------------
//--------------------------------------------------------------------

#include <IGESData_DirChecker.hxx>
#include <IGESData_Dump.hxx>
#include <IGESData_IGESDumper.hxx>
#include <IGESData_IGESReaderData.hxx>
#include <IGESData_IGESWriter.hxx>
#include <IGESData_ParamReader.hxx>
#include <IGESDimen_DimensionDisplayData.hxx>
#include <IGESDimen_ToolDimensionDisplayData.hxx>
#include <Interface_Check.hxx>
#include <Interface_CopyTool.hxx>
#include <Interface_EntityIterator.hxx>
#include <Interface_ShareTool.hxx>
#include <Message_Messenger.hxx>
#include <TCollection_HAsciiString.hxx>
#include <TColStd_HArray1OfInteger.hxx>

IGESDimen_ToolDimensionDisplayData::IGESDimen_ToolDimensionDisplayData ()  {  }


void  IGESDimen_ToolDimensionDisplayData::ReadOwnParams
  (const Handle(IGESDimen_DimensionDisplayData)& ent,
   const Handle(IGESData_IGESReaderData)& /* IR */, IGESData_ParamReader& PR) const
{
  //Standard_Boolean st; //szv#4:S4163:12Mar99 moved down
  Standard_Integer tempDimType;
  Standard_Integer tempLabelPos;
  Standard_Integer tempCharSet;
  Handle(TCollection_HAsciiString) tempLString;
  Standard_Real tempWitLineAng;
  Standard_Integer tempDeciSymb;
  Standard_Integer tempTextAlign;
  Standard_Integer tempTextLevel;
  Standard_Integer tempTextPlace;
  Standard_Integer tempArrHeadOrient;
  Standard_Real tempInitVal;
  Standard_Integer tempNbProps;
  Handle(TColStd_HArray1OfInteger) tempSuppleNotes;
  Handle(TColStd_HArray1OfInteger) tempStartInd;
  Handle(TColStd_HArray1OfInteger) tempEndInd;

  //szv#4:S4163:12Mar99 `st=` not needed
  PR.ReadInteger(PR.Current(),"Number of Properties",tempNbProps);
  PR.ReadInteger(PR.Current(),"Dimension Type", tempDimType);
  PR.ReadInteger(PR.Current(),"Label Position", tempLabelPos);
  if (PR.DefinedElseSkip())
    PR.ReadInteger(PR.Current(),"Character Set", tempCharSet); //szv#4:S4163:12Mar99 `st=` not needed
  else
    tempCharSet = 1;

  //szv#4:S4163:12Mar99 `st=` not needed
  PR.ReadText(PR.Current(),"L String", tempLString);
  PR.ReadInteger(PR.Current(),"Decimal Symbol",tempDeciSymb);
  if (PR.DefinedElseSkip())
    PR.ReadReal(PR.Current(),"Witness Line Angle",tempWitLineAng); //szv#4:S4163:12Mar99 `st=` not needed
  else
    tempWitLineAng = M_PI / 2;

  PR.ReadInteger(PR.Current(),"Text Alignment",tempTextAlign); //szv#4:S4163:12Mar99 `st=` not needed
  if (PR.DefinedElseSkip())
    PR.ReadInteger(PR.Current(),"Text Level",tempTextLevel); //szv#4:S4163:12Mar99 `st=` not needed
  else
    tempTextLevel = 0;

  if (PR.DefinedElseSkip())
    PR.ReadInteger(PR.Current(),"Text Place",tempTextPlace); //szv#4:S4163:12Mar99 `st=` not needed
  else
    tempTextPlace = 0;

  //szv#4:S4163:12Mar99 `st=` not needed
  PR.ReadInteger(PR.Current(),"ArrowHeadOrientation",tempArrHeadOrient);
  PR.ReadReal(PR.Current(),"Initial Value",tempInitVal);
  Standard_Integer tempnbval;
  Standard_Boolean st = PR.ReadInteger( PR.Current(), "No. of supplementary notes", tempnbval);
  if (st && tempnbval > 0)
    {
      tempSuppleNotes = new TColStd_HArray1OfInteger(1,tempnbval);
      tempStartInd = new TColStd_HArray1OfInteger(1,tempnbval);
      tempEndInd = new TColStd_HArray1OfInteger(1,tempnbval);
      for (Standard_Integer i = 1; i <= tempnbval; i++)
	{
          Standard_Integer anote,astart,anend;
          //st = PR.ReadInteger(PR.Current(), "Supplementary Notes", anote); //szv#4:S4163:12Mar99 moved in if
	  if (PR.ReadInteger(PR.Current(), "Supplementary Notes", anote))
	    tempSuppleNotes->SetValue(i,anote);
          //st = PR.ReadInteger(PR.Current(),"Start Index", astart); //szv#4:S4163:12Mar99 moved in if
	  if (PR.ReadInteger(PR.Current(),"Start Index", astart))
	    tempStartInd->SetValue(i,astart);
          //st = PR.ReadInteger(PR.Current(),"End Index",anend); //szv#4:S4163:12Mar99 moved in if
	  if (PR.ReadInteger(PR.Current(),"End Index",anend))
	    tempEndInd->SetValue(i,anend);
	}
    }

  DirChecker(ent).CheckTypeAndForm(PR.CCheck(),ent);
  ent->Init
    (tempNbProps,   tempDimType, tempLabelPos, tempCharSet, tempLString,
     tempDeciSymb,  tempWitLineAng, tempTextAlign, tempTextLevel,
     tempTextPlace, tempArrHeadOrient, tempInitVal, tempSuppleNotes,
     tempStartInd,  tempEndInd );
}

void  IGESDimen_ToolDimensionDisplayData::WriteOwnParams
  (const Handle(IGESDimen_DimensionDisplayData)& ent, IGESData_IGESWriter&  IW)
const
{
  IW.Send(ent->NbPropertyValues());
  IW.Send(ent->DimensionType());
  IW.Send(ent->LabelPosition());
  IW.Send(ent->CharacterSet());
  IW.Send(ent->LString());
  IW.Send(ent->DecimalSymbol());
  IW.Send(ent->WitnessLineAngle());
  IW.Send(ent->TextAlignment());
  IW.Send(ent->TextLevel());
  IW.Send(ent->TextPlacement());
  IW.Send(ent->ArrowHeadOrientation());
  IW.Send(ent->InitialValue());

  Standard_Integer nbval = ent->NbSupplementaryNotes();
  IW.Send(nbval);
  for (Standard_Integer i = 1; i <= nbval; i++)
    {
      IW.Send(ent->SupplementaryNote(i));
      IW.Send(ent->StartIndex(i));
      IW.Send(ent->EndIndex(i));
    }
}

void  IGESDimen_ToolDimensionDisplayData::OwnShared
  (const Handle(IGESDimen_DimensionDisplayData)& /* ent */, Interface_EntityIterator& /* iter */) const
{
}

void  IGESDimen_ToolDimensionDisplayData::OwnCopy
  (const Handle(IGESDimen_DimensionDisplayData)& another,
   const Handle(IGESDimen_DimensionDisplayData)& ent, Interface_CopyTool& /* TC */) const
{
  Handle(TColStd_HArray1OfInteger) EndList;
  Handle(TColStd_HArray1OfInteger) StartList;
  Handle(TColStd_HArray1OfInteger) NotesList;

  Standard_Integer upper = another->NbSupplementaryNotes();
  if (upper > 0)
    {
      EndList = new TColStd_HArray1OfInteger(1,upper);
      StartList = new TColStd_HArray1OfInteger(1,upper);
      NotesList = new TColStd_HArray1OfInteger(1,upper);
      for (Standard_Integer i = 1;i <= upper;i++)
	{
          EndList->SetValue(i,another->EndIndex(i));
          StartList->SetValue(i,another->StartIndex(i));
          NotesList->SetValue(i,another->SupplementaryNote(i));
	}
    }
  Standard_Integer tempNbPropertyValues = another->NbPropertyValues();
  Standard_Integer tempDimensionType    = another->DimensionType();
  Standard_Integer tempLabelPos         = another->LabelPosition();
  Standard_Integer tempCharSet          = another->CharacterSet();
  Handle(TCollection_HAsciiString) tempLS =
    new TCollection_HAsciiString(another->LString());
  Standard_Integer tempSymbol           = another->DecimalSymbol();
  Standard_Real    tempAngle            = another->WitnessLineAngle();
  Standard_Integer tempAlign            = another->TextAlignment();
  Standard_Integer tempLevel            = another->TextLevel();
  Standard_Integer tempPlacement        = another->TextPlacement();
  Standard_Integer tempArrowHead        = another->ArrowHeadOrientation();
  Standard_Real    tempInitial          = another->InitialValue();

  ent->Init(tempNbPropertyValues, tempDimensionType,tempLabelPos,tempCharSet,
	    tempLS,tempSymbol,tempAngle,tempAlign,tempLevel,tempPlacement,
	    tempArrowHead,tempInitial,NotesList,StartList,EndList);
}

Standard_Boolean  IGESDimen_ToolDimensionDisplayData::OwnCorrect
  (const Handle(IGESDimen_DimensionDisplayData)& ent) const
{
  Standard_Boolean res = (ent->NbPropertyValues() != 14);
  if (!res) return res;
  Handle(TColStd_HArray1OfInteger) EndList;
  Handle(TColStd_HArray1OfInteger) StartList;
  Handle(TColStd_HArray1OfInteger) NotesList;

  Standard_Integer upper = ent->NbSupplementaryNotes();
  if (upper > 0)
    {
      EndList   = new TColStd_HArray1OfInteger(1,upper);
      StartList = new TColStd_HArray1OfInteger(1,upper);
      NotesList = new TColStd_HArray1OfInteger(1,upper);
      for (Standard_Integer i = 1;i <= upper;i++)
	{
          EndList->SetValue  (i,ent->EndIndex(i));
          StartList->SetValue(i,ent->StartIndex(i));
          NotesList->SetValue(i,ent->SupplementaryNote(i));
	}
    }
  ent->Init
    (14, ent->DimensionType(),ent->LabelPosition(),ent->CharacterSet(),
     ent->LString(),      ent->DecimalSymbol(),ent->WitnessLineAngle(),
     ent->TextAlignment(),ent->TextLevel(),    ent->TextPlacement(),
     ent->ArrowHeadOrientation(),ent->InitialValue(),
     NotesList,StartList,EndList);
  return res;    // nbpropertyvalues=14
}

IGESData_DirChecker  IGESDimen_ToolDimensionDisplayData::DirChecker
  (const Handle(IGESDimen_DimensionDisplayData)& /* ent */ ) const
{
  IGESData_DirChecker DC(406,30); // type=406, Form no. = 30
  DC.Structure(IGESData_DefVoid);
  DC.GraphicsIgnored();
  DC.BlankStatusIgnored();
  DC.SubordinateStatusRequired(02);
  DC.UseFlagRequired(02);
  DC.HierarchyStatusIgnored();
  return DC;
}

void  IGESDimen_ToolDimensionDisplayData::OwnCheck
  (const Handle(IGESDimen_DimensionDisplayData)& ent,
   const Interface_ShareTool& , Handle(Interface_Check)& ach) const
{
  if (ent->NbPropertyValues() != 14)
    ach->AddFail("The No. of property values != 14 ");
  if (ent->DimensionType() < 0 || ent->DimensionType() > 2)
    ach->AddFail("Incorrect Dimension Type");
  if (ent->LabelPosition() < 0 || ent->LabelPosition() > 4)
    ach->AddFail("Incorrect Preferred Label Position");
  if (!(ent->CharacterSet() == 1 || ent->CharacterSet() == 1001 ||
        ent->CharacterSet() == 1002 || ent->CharacterSet() == 1003))
    ach->AddFail("Incorrect Character Set");
  if (ent->DecimalSymbol() != 0 && ent->DecimalSymbol() != 1)
    ach->AddFail("Incorrect Decimal Symbol");
  if (ent->TextAlignment() != 0 && ent->TextAlignment() != 1)
    ach->AddFail("Incorrect Text Alignment");
  if (ent->TextLevel() < 0 || ent->TextLevel() > 2)
    ach->AddFail("Incorrect Text Level");
  if (ent->TextPlacement() < 0 || ent->TextPlacement() > 2)
    ach->AddFail("Incorrect Text Placement");
  if (ent->ArrowHeadOrientation() != 0 && ent->ArrowHeadOrientation() != 1)
    ach->AddFail("Incorrect ArrowHead Orientation");
  for (Standard_Integer upper = ent->NbSupplementaryNotes(), i = 1;
       i <= upper; i++) {
    if (ent->SupplementaryNote(i) < 1 ||
	ent->SupplementaryNote(i) > 4)
      ach->AddFail("Incorrect First supplement note");
  }
}

void  IGESDimen_ToolDimensionDisplayData::OwnDump
  (const Handle(IGESDimen_DimensionDisplayData)& ent, const IGESData_IGESDumper& /* dumper */,
   Standard_OStream& S, const Standard_Integer level) const
{
  S << "IGESDimen_DimensionDisplayData\n"
    << "No. of property values : " << ent->NbPropertyValues() << "\n"
    << "DimensionType : "  << ent->DimensionType() ;
  switch (ent->DimensionType()) {
    case 0  :  S << " (Ordinary)\n";  break;
    case 1  :  S << " (Reference)\n"; break;
    case 2  :  S << " (Basic)\n";     break;
    default :  S << " (Incorrect Value)\n"; break;
  }

  S << "Preferred Label Position : "  << ent->LabelPosition();
  switch (ent->LabelPosition()) {
    case 0  :  S << " (Does not exist)\n";     break;
    case 1  :  S << " (Before Measurement)\n"; break;
    case 2  :  S << " (After Measurement)\n";  break;
    case 3  :  S << " (Above Measurement)\n";  break;
    case 4  :  S << " (Below Measurement)\n";  break;
    default :  S << " (Incorrect Value)\n";    break;
  }

  S << "Character set interpretation : " << ent->CharacterSet() ;
  switch (ent->CharacterSet()) 
    {
    case 1    : S << " (Standard ASCII)\n"; break;
    case 1001 : S << " (Symbol Font 1)\n";  break;
    case 1002 : S << " (Symbol Font 2)\n";  break;
    case 1003 : S << " (Drafting Font)\n";  break;
    default   : S << " (Not meaningful)\n"; break;
  }

  S << "LString : ";
  IGESData_DumpString(S,ent->LString());
  S << "\n"
    << "Decimal Symbol : ";
  if (ent->DecimalSymbol() == 0)  S << "0 (.)\n";
  else                            S << "1 (,)\n";

  S << "Witness Line Angle : " << ent->WitnessLineAngle() << "\n"
    << "Text Alignment : " ;
  if      (ent->TextAlignment() == 0 )    S << "0 (Horizontal)\n";
  else if (ent->TextAlignment() == 1 )    S << "1 (Parallel)\n";
  else     S <<  ent->TextAlignment() << " (Incorrect Value)\n";

  S << "Text Level : " << ent->TextLevel();
  switch (ent->TextLevel()) {
    case 0  :  S << " (Neither above nor below)\n"; break;
    case 1  :  S << " (Above)\n"; break;
    case 2  :  S << " (Below)\n"; break;
    default :  S << " (Incorrect Value)\n"; break;
  }

  S << "Preferred Text placement : " << ent->TextPlacement();
  switch (ent->TextPlacement()) {
    case 0  :  S << " (Between witness lines)\n"; break;
    case 1  :  S << " (Outside near the first witness line)\n"; break;
    case 2  :  S << " (Outside near second witness line)\n"; break;
    default :  S << " (Incorrect Value)\n"; break;
  }

  S << "Arrow Head Orientation : "  << ent->ArrowHeadOrientation();
  if      (ent->ArrowHeadOrientation() == 0) S << " (In, pointing out)\n";
  else if (ent->ArrowHeadOrientation() == 1) S << " (Out, pointing in)\n";
  else                                       S << " (Incorrect Value)\n";

  Standard_Integer nbnotes = ent->NbSupplementaryNotes();
  S << " Primary Dimension Value : " << ent->InitialValue() << "\n"
    << " Number of Supplementary Notes : " << nbnotes << "\n"
    << "Supplementary Notes , "
    << " Start Index , "
    << " End   Index :\n";
  IGESData_DumpVals(S,-level,1, nbnotes,ent->EndIndex);
  S << "\n";
  if (level > 4)
    for (Standard_Integer i = 1; i <= nbnotes; i ++)
      {
	S << "[" << i << "]:\n"
	  << "Supplementary Note : " << ent->SupplementaryNote(i)
	  << ", Start Index : " << ent->StartIndex(i)
	  << ", End Index : "   << ent->EndIndex(i) << "\n";
      }
  S << std::endl;
}
