#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>

#include <nlohmann/json.hpp>

#include <iostream>
#include <fstream>
#include <string>

using namespace cv;
using nlohmann::json;
using std::string;

#define H 800
#define W 300
#define M 30
#define R 60

Mat source_image = Mat::zeros(Size(H,W),CV_8UC1);
void render(int i, int j, int y_s, int x_s, Mat *img) {
   if(i >= y_s && i <= y_s+R-1 && j >= x_s && j <= x_s+R-1) {
      source_image.at<uchar>(i,j)=img->at<uchar>(i-y_s,j-x_s);
   }
}

int main(int argc, char** argv) {

   // FACTION
   int fac; 
   if(argc <= 1) {
      std::cout << "0:U,1:SK,2:M,3:N,4:S";
      std::cin >> fac;
   }
   else fac = std::atoi(argv[1]);

   std::ifstream ff("cards/factions.json");
   json factions = json::parse(ff);
   string faction = factions[fac];
   
   // NAME
   string name; 
   if(argc <= 2) std::cin >> name;
   else name = argv[2];
   std::ifstream f("cards/"+faction+"/"+name+".json");
   json data = json::parse(f);

   // LOAD IMAGES
   Mat i_look = imread("cards/"+faction+"/images/"+name+".png",IMREAD_GRAYSCALE);
   Mat i_faction = imread("cards/images/factions/"+faction+".png",IMREAD_GRAYSCALE);
   Mat i_line = imread("cards/images/lines/"+string(data["line"])+".png",IMREAD_GRAYSCALE);
   
   // RENDER IMAGES
   std::vector<Mat> i_traits;
   for(auto trait : data["traits"]) {
      i_traits.push_back(imread("cards/images/traits/"+string(trait)+".png",IMREAD_GRAYSCALE));
   }

   for(int i=0;i<source_image.rows;i++)
      for(int j=0;j<source_image.cols;j++)
         source_image.at<uchar>(i,j)=i_look.at<uchar>(i,j);
   
   // RENDER POWER AND TRAITS
   string bruh = std::to_string((int)data["power"]); 
   for(int i=0;i<source_image.rows;i++) {
      for(int j=0;j<source_image.cols;j++) {
         // Vlevo nahoře sílu
         putText(
            source_image, 
            bruh, 
            Point(M,M),
            FONT_HERSHEY_COMPLEX_SMALL, 
            1, 
            Scalar(0,0,0), 
            2
         );

         render(i,j, M,W/2-R/2, &i_faction);
         render(i,j, M,W-M-R, &i_line);
         // Traits
         for(int k = 0; k < i_traits.size(); k++)
            render(i,j, H-M-R,W-M-R*(k+1), &i_traits[k]);
      }
   }

   imshow("Result",source_image);
   waitKey(0);
   return 0;


}
