//---------------------------------------------------------------------------
// Controled Not
//---------------------------------------------------------------------------
#include <sstream>
#include <stdlib.h>
#include "QCnot.h"
//---------------------------------------------------------------------------
QCNot::QCNot(int x,int y) :QCircuit(x,y) {
  Name = GetTypeStr();
  Target = Y;
}
//---------------------------------------------------------------------------
QCNot::QCNot(int x,int y, string Param) :QCircuit(x,y) {
  Name = GetTypeStr();
  Target = atoi(Param.c_str());
}
//---------------------------------------------------------------------------
void
QCNot::Draw(QDraw *qDraw) {
  int GridSize = qDraw->GetGridSize();
  int UnitSize = qDraw->GetUnitSize();

  int tx = X;
  int ty = Target;

  int tx1 = tx*GridSize + GridSize/2;
  int ty1 = ty*GridSize + GridSize/2;
  int tx2 = X*GridSize + GridSize/2;
  int ty2 = Y*GridSize + GridSize/2;
  qDraw->SetPenColor(clBlack);
  qDraw->DrawLine(tx1,ty1,tx2,ty2);
  qDraw->SetBrushColor(clBlack);

  qDraw->Ellipse(tx1-4,ty1-4,tx1+5,ty1+5);


  int d = (GridSize-UnitSize)/2;
  int x1 = X * GridSize+d;
  int y1 = Y * GridSize+d;
  int x2 = x1 + UnitSize;
  int y2 = y1 + UnitSize;

  qDraw->SetBrushColor(clWhite);
  qDraw->FillRect(x1,y1,x2,y2);
  qDraw->SetPenColor(clBlack);
  qDraw->SetBrushColor(clWhite);
  qDraw->Ellipse(x1,y1,x2,y2);
  qDraw->DrawLine(x1+UnitSize/2,y1,x1+UnitSize/2,y2);
  qDraw->DrawLine(x1,y1+UnitSize/2,x2,y1+UnitSize/2);
}
//---------------------------------------------------------------------------
void QCNot::Reverse(int y) {
  Y = y-Y;
  Target = y - Target;
}
//---------------------------------------------------------------------------
string
QCNot::GetCalcText(void) {
  ostringstream os;
  os << "CNOT(";
  os << "q[" << Y << "],";
  os << "q[" << Target << "])";
  return os.str();
}
//---------------------------------------------------------------------------
void
QCNot::DrawPS(QPSDraw *psDraw) {
  int GridSize = psDraw->GetGridSize();
  int UnitSize = psDraw->GetUnitSize();

  int tx = X;
  int ty = Target;

  int tx1 = tx*GridSize + GridSize/2;
  int ty1 = ty*GridSize + GridSize/2;
  int tx2 = X*GridSize + GridSize/2;
  int ty2 = Y*GridSize + GridSize/2;
  psDraw->DrawLine(tx1,ty1,tx2,ty2);
  psDraw->DrawFillCircle(tx1,ty1,4);

  int d = (GridSize-UnitSize)/2;
  int x1 = X * GridSize+d;
  int y1 = Y * GridSize+d;
  int x2 = x1 + UnitSize;
  int y2 = y1 + UnitSize;

  psDraw->FillRect(x1,y1,x2,y2);

  psDraw->DrawCircle(X*GridSize + GridSize/2,Y*GridSize + GridSize/2,UnitSize/2);
  psDraw->DrawLine(x1+UnitSize/2,y1,x1+UnitSize/2,y2);
  psDraw->DrawLine(x1,y1+UnitSize/2,x2,y1+UnitSize/2);
}
//---------------------------------------------------------------------------
string
QCNot::GetParam(void) {
  ostringstream os;
  os << Target;
  return os.str();
}
//---------------------------------------------------------------------------
TRect
QCNot::GetOccupiedRect() {
  TRect rc;
  rc.left = X;
  rc.right = X + 1;
  rc.top = Y;
  rc.bottom = Y + 1;
  if (Target < Y) {
    rc.top = Target;
  } else {
    rc.bottom = Target + 1;
  }
  return rc;
}
//---------------------------------------------------------------------------
QCircuit *
QCNot::Clone() {
  QCNot * qc = new QCNot(X, Y);
  qc->SetTarget(GetTarget());
  return (QCircuit*)qc;
}
//---------------------------------------------------------------------------
