#ifndef MTHREAD_H
#define MTHREAD_H

#include <mutex>
#include <atomic>
#include <thread>
#include <complex>
#include <condition_variable>
#include "libpng_wrapper.hpp"

struct mthread_status {
  std::mutex status_lock;
  unsigned int row_load;
  bool share_finished;
  bool searching;

  bool div_syn;
  std::mutex ack_lk;
  std::mutex syn_ack_lk;
  bool div_error;

  std::condition_variable msg_notify;
};

struct mthread_divinfo {
  uint32_t x_min, x_max;
  uint32_t y_min, y_max;
};

class mthread {
  public:
    mthread(unsigned int x_mn, unsigned int x_mx, 
        std::complex<double> c_min, std::complex<double> c_max, 
         unsigned int inf_cutoff, unsigned int max_iter, png& image, double *g_vmap, unsigned int *g_histogram, 
        mthread **worker_list, unsigned int id, unsigned int jobs, std::atomic<uint32_t>& progress);
    ~mthread();
    void join();
    void dispatch();


    struct mthread_status status;
    unsigned int *histogram;
  protected:
    const unsigned int min_lines = 4;
    const unsigned int x_min_orig, x_max_orig;
    const std::complex<double> c_min;
    const std::complex<double> c_max;
    const unsigned int inf_cutoff;
    const unsigned int max_iter;
    png& image;
    double *vmap;
    const unsigned int id;
    mthread **workers;
    std::complex<double> c_current_min;
    std::complex<double> c_current_max;
    std::complex<double> step;
    std::thread *my_thread;
    const unsigned int worker_cnt;
    std::atomic<uint32_t>& progress;

    uint32_t x_min, x_max, y_min, y_max;
    uint32_t on_x, on_y;
    unsigned int divisions;
    void render();
    int state;
    struct mthread_divinfo divide();


};

#endif
