#include <iostream>
#include <fstream>
#include <memory>
#include <string>
#include <cstdio>
#include <vector>

#include "stl_parser.hpp"
#include "point.hpp"
#include "vector.hpp"
#include "triangle.hpp"

using namespace visual_engine;

bin_stl_parser::bin_stl_parser(std::string path) {
    std::fstream fs(path, std::fstream::in | std::fstream::binary);
    if (!fs.is_open()) {
        std::cout << "wrong path to stl file" << std::endl;
        return;
    }

    unsigned int triag_num;
    fs.seekg(stl_start_pos);
    fs.read(reinterpret_cast<char*>(&triag_num), sizeof(unsigned int));
    count_ = triag_num;
    std::cout << triag_num << std::endl;

    for (unsigned idx = 0; idx != count_; ++idx) {
        vector norm = read_vector(fs);
        point  a    = read_point(fs);
        point  b    = read_point(fs);
        point  c    = read_point(fs);
        fs.ignore(stl_attribute_len);
        triags_.emplace_back(a, b, c, norm);
    }
}

point bin_stl_parser::read_point(std::fstream& fs) const {
    float x = 0, y = 0, z = 0;
    fs.read(reinterpret_cast<char*>(&x), sizeof(float));
    fs.read(reinterpret_cast<char*>(&y), sizeof(float));
    fs.read(reinterpret_cast<char*>(&z), sizeof(float));
    return point{x, y, z};
}

vector bin_stl_parser::read_vector(std::fstream& fs) const {
    float x = 0, y = 0, z = 0;
    fs.read(reinterpret_cast<char*>(&x), sizeof(float));
    fs.read(reinterpret_cast<char*>(&y), sizeof(float));
    fs.read(reinterpret_cast<char*>(&z), sizeof(float));
    return vector{x, y, z};
}

std::vector<triangle>::iterator bin_stl_parser::begin() { return triags_.begin(); }
std::vector<triangle>::iterator bin_stl_parser::end()   { return triags_.end();   }
