/* 
 * File:   BatchProcessing.h
 * Author: jorge
 *
 * Created on 8 de octubre de 2013, 17:21
 */

#ifndef _BATCHPROCESSING_H
#define	_BATCHPROCESSING_H

#include <limits>
#include <QTimer>
#include <iostream>
#include <string>
#include <fstream>
#include <time.h>
#include <initializer_list>

#include "ui_BatchProcessing.h"

#include "geometry.h"
#include "colormap.hpp"
#include "poseEstimation.h"
#include <Stereo.h>
#include <munkres.h>

#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <boost/filesystem.hpp>
#include <boost/format.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/math/special_functions/fpclassify.hpp>


#include <pcl/common/impl/centroid.hpp>
#include <pcl/common/transforms.h>
#include <pcl/common/common.h>
#include <pcl/common/distances.h>
#include <pcl/common/common_headers.h>

#include <pcl/point_traits.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h> 

#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/pcl_visualizer.h>

#include <pcl/features/normal_3d.h>

#include <pcl/filters/statistical_outlier_removal.h>

#include <pcl/filters/voxel_grid.h>

#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>

#include <pcl/sample_consensus/sac_model_normal_parallel_plane.h>

#include <pcl/ModelCoefficients.h>

#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>


#include <pcl/features/feature.h> // for compute3DCentroid 

#include <pcl/surface/mls.h>

#include <Eigen/Dense>

#include <vtkRenderer.h>
#include <vtkRendererCollection.h>
#include <vtkCamera.h>

class BatchProcessing : public QMainWindow 
{
    Q_OBJECT
    
    public:
        BatchProcessing();
        virtual ~BatchProcessing();
        void doProcessing();
        void poseEstimatorWorker();
        void batchPoseEstimatorWorker();
        
        bool doMFP();
        void visualization();
        bool doVIS(string pcd_file);
        bool doVIS(pcl::PointCloud<pcl::PointXYZRGB>::Ptr& cloud);
        void singleFolderProcessing(const boost::filesystem::path& folder);
        void singleFolderProcessing(const boost::filesystem::path& folder,const boost::filesystem::path& left_path,const boost::filesystem::path& right_path,const boost::filesystem::path& left_color_path);
        bool stereo(string left,string right,string disparity, string normalized_disparity,string filestorage);
        bool calculatePointCloud(string disparity_filestorage,string color_image,string pcd_cloud);
        bool filterPointCloud(string cloud,string background, string filtered_cloud);
        void readCloud(string cloud_file,pcl::PointCloud<pcl::PointXYZRGB>::Ptr& cloud);
        
        void drawPose(PoseEstimation& estimator,PedestrianModel& model);
        void drawSimplePose(PoseEstimation& estimator,PedestrianModel& model);
        
        void keyboardHandler(const pcl::visualization::KeyboardEvent& event);
        
        void drawEllipse(Ellipse::Ptr ellipse,double r,double g,double b,string id);
        void drawGrid(pcl::PointXYZRGB start_point,int number_cells,double cell_size,double r,double g,double b,string id);
        
        void setCameraPose(pcl::PointXYZRGB c_position,pcl::PointXYZRGB c_look_at,pcl::PointXYZRGB c_orientation);
        
        void trialPloter(void);
        
        void readXMLlist(std::string list_path,std::vector<boost::filesystem::path>& paths,std::vector<double>& heights);
        
    public slots:
        
        void startProcessing();
        void startMFP();
        void startVisualization();
        void startPoseEstimation();
        void startBatchPoseEstimation();
        void startPlotTrialResults();
        
        void stopProcessing();
        void openDir();
        void update();
        void update_mfp();
        

    private:
        
        Ui::BatchProcessing widget;
        
        unsigned int number_of_threads;
        boost::thread* process;
        boost::thread* mfprocess;
        boost::thread* visprocess;
        boost::thread* generic_process;
        boost::thread* visualization_process;
        boost::mutex mtx_;
        boost::mutex mtx_mfp_;
        boost::mutex draw;
        
        int start_frame;
        int end_frame;
        int current_frame;
        string folder;
        
        double current_folder_progress;
        
        QTimer *timer;
        
        bool working;
        bool finished;
        bool force_stop;
        
        bool calculate3d;
        bool calculateStereo;
        bool calculateBackgroundSubtraction;
        
        bool doFiltering;
        bool useBackgroundSubtraction;
        bool useGroundPlaneEstimation;
        bool useRange;
        
        bool update_viewer;
        
        bool processed_;
        uint current_iteration_;
        bool stop_;
        
        boost::filesystem::path main_folder;
        boost::filesystem::path trial_folder;
        
        string current_file_name;
        
        bool show_samples_;
        
        bool new_pose_;
        
        bool save_pose_text_;
        bool save_screenshot_;
        
        bool interactive_;
        bool use_external_list_;
        std::string external_list_path_;
        
        double current_model_height_;
        
        pcl::PointXYZRGB c_position_;
        pcl::PointXYZRGB c_look_at_;
        pcl::PointXYZRGB c_orientation_;
        
        
        boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
        pcl::PointCloud<pcl::PointXYZRGB>::Ptr buffer;
};


bool sortContoursLength(const vector<cv::Point>& c1,const vector<cv::Point>& c2);

#endif	/* _BATCHPROCESSING_H */
