#include "ChessboardVisualizer.hpp"

size_t ChessboardVisualizer::GetMaxBoardWidth() {
    std::string temp;

    temp.append(3, ' ');

    temp += BaseVisualizer::TOP_LEFT_CORNER;
    for (int i = 0; i < 8; i++) {
      for (int j = 0; j < 7; j++) {
        temp += BaseVisualizer::HORIZONTAL_LINE;
      }
    }
    temp += BaseVisualizer::TOP_RIGHT_CORNER;

    return BaseVisualizer::CountVisibleCharacters(temp);
}

void ChessboardVisualizer::GenerateTopBottomBorder(bool top, bool single) {
    std::string temp;

    temp.append(3, ' '); // ToDo: Padding?

    temp += (top)
                ? ((single)
                       ? BaseVisualizer::TOP_LEFT_CORNER_SINGLE
                       : BaseVisualizer::TOP_LEFT_CORNER)
                : ((single)
                       ? BaseVisualizer::BOTTOM_LEFT_CORNER_SINGLE
                       : BaseVisualizer::BOTTOM_LEFT_CORNER);
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 7; j++) {
            temp += (single) ? BaseVisualizer::HORIZONTAL_LINE_SINGLE : BaseVisualizer::HORIZONTAL_LINE;
        }
    }
    display_vector.push_back({temp + ((top) ? ((single) ? BaseVisualizer::TOP_RIGHT_CORNER_SINGLE : BaseVisualizer::TOP_RIGHT_CORNER) : ((single) ? BaseVisualizer::BOTTOM_RIGHT_CORNER_SINGLE : BaseVisualizer::BOTTOM_RIGHT_CORNER))});
}

void ChessboardVisualizer::GenerateElement() {
  BaseVisualizer::ClearTerminal();

  GeneratePlayers();

  GenerateChessboard();

  //GenerateDisplayVector();
}

void ChessboardVisualizer::GeneratePlayers() {
  std::string result;
  result.append(3, ' ');
  display_vector.push_back({result + CHESSBOARD->GetPlayer(ChessPieceColor::White)->GetName()
                                           + " vs. " + CHESSBOARD->GetPlayer(ChessPieceColor::Black)->GetName()});
}

void ChessboardVisualizer::GenerateChessboard() {
  std::vector<std::string> temp;
  for (int rank = 8; rank >= 1; rank--) {
    if (rank == 8) GenerateTopBottomBorder(true, true);
    for (int heightOfField = 0; heightOfField < 3; heightOfField++) {
      for (char file = 'A'; file <= 'H'; file++) {
        if (file == 'A') {
          temp.push_back((heightOfField == 1) ? " " + std::to_string(rank) + " " : std::string(3, ' '));
          temp.push_back(BaseVisualizer::VERTICAL_LINE_SINGLE);
        }

        temp.push_back(GenerateBoardField(file, rank, heightOfField));

        if (file == 'H') {
          temp.push_back(BaseVisualizer::VERTICAL_LINE_SINGLE);
        }
      }
      display_vector.push_back(temp);
      temp.clear();
    }
    if (rank == 1) {
      GenerateTopBottomBorder(false, true);
      GenerateFiles();
    }
  }
}

std::string ChessboardVisualizer::GenerateBoardField(char file, int rank, int height) {
  ChessPiecePosition* position = new ChessPiecePosition(file, rank);
  if (height == 1 && !CHESSBOARD->IsEmptyField(position)) {
  	ChessPiece* piece = CHESSBOARD->GetChessPiece(position);
  	return std::string(3, ' ') + piece->GetUnicode() + std::string(3, ' ');
  }
  return std::string(7, ' ');
}

void ChessboardVisualizer::GenerateFiles() {
  std::string temp;

  for (char file = 'A'; file <= 'H'; file++) {
    if (file == 'A') {
      temp += (std::string(4, ' '));
    }

    temp += (std::string(3, ' ') + std::string(1, file) + std::string(3, ' '));

    if (file == 'H') {
      temp += " ";
     }
  }
  display_vector.push_back({temp});
}


// board[2] bis board[25] Feld des Schachbretts
// in vectoren von 2 bis 25 index von 2 bis 9
void ChessboardVisualizer::DisplayElement() {
  size_t size;
  std::string temp;
  for (int row = 0; row < display_vector.size(); ++row) {
    for (int column = 0; column < display_vector[row].size(); ++column) {
      if (row >= 2 && row <= 25 && column >= 2 && column <= 9) {
        bool isSecondRowOfField = (row % 3 == 2);
        bool isBlackWhite = (column % 2 == row % 2);

        if ((row - 1) % 3 == 0) { // Change after 3 rows
          if (isSecondRowOfField) {
            this->SetConsoleColor(isBlackWhite ? WHITE : BLACK, isBlackWhite ? BLACK : WHITE);
          } else {
            this->SetConsoleColor(isBlackWhite ? BLACK : WHITE, isBlackWhite ? WHITE : BLACK);
          }
        } else {
          if (isSecondRowOfField) {
            this->SetConsoleColor(isBlackWhite ? BLACK : WHITE, isBlackWhite ? WHITE : BLACK);
          } else {
            this->SetConsoleColor(isBlackWhite ? WHITE : BLACK, isBlackWhite ? BLACK : WHITE);
          }
        }
      }
      std::cout << display_vector[row][column];
      this->SetConsoleColor(DEFAULT, DEFAULT);
    }
    this->SetConsoleColor(DEFAULT, DEFAULT);

    std::cout << std::endl;
  }
}

/*void ChessboardVisualizer::GenerateDisplayVector() {
  std::string temp;
  size_t size;

  for (auto& row : draw_vector) {
    if (row.size() > 1) {
      for (const auto& element : row) {
        temp += element;
      }
      display_vector.push_back(FillStringToMaxLength(temp));
      temp = "";
    } else {
      display_vector.push_back(FillStringToMaxLength(row[0]));
    }
  }
}

std::string ChessboardVisualizer::FillStringToMaxLength(std::string& str) {
  size_t size = BaseVisualizer::CountVisibleCharacters(str);
  return ((size == MAX_MENU_WIDTH)
              ? str
              : str.append(std::string(MAX_MENU_WIDTH - size, ' ')));
}*/