#include <stdlib.h>
#include <stdio.h>
#include "quad.h"

QuadMesh::QuadMesh(Triangulation *tri)
{
    _tri = tri;
    for (Triangle *t = _tri->getTri(); t < _tri->getTri()+ _tri->getTriangleCount(); ++t)
    {
        t->set_flag(-1);
        for (int i = 0; i < 3; i++)
        {
            if (t->get_adjacent(i) != NULL)
                add_edge(t, i);
        }
    }
    
    for (_item = _edge_map.begin(); _item != _edge_map.end();_item++)
    {
	Triangle *t = _item->second.first;
	int edge = _item->second.second;
	Triangle *adj = t->get_adjacent(edge);
	int opp = t->get_opp(edge);
	if ((t->get_flag() == -1) && (adj->get_flag() == -1))
	{
	    Quad *nq = new Quad(t->get_vertex(edge), t->get_vertex((edge+1)%3), adj->get_vertex(opp), adj->get_vertex((opp+1)%3));
	    _quad_list.push_back(nq);
	    t->set_flag(1);
	    adj->set_flag(1);
	    _edge_map.erase(_item);
	    _item--;
	}
    }
    
    for (_item = _edge_map.begin(); _item != _edge_map.end();_item++)
    {
        Triangle *t = _item->second.first;
        int edge = _item->second.second;
        if (t->get_flag() == -1)
        {
            _tri_list.push_back(t);
// 	    printf("tri --> %d %d %d\n", t->get_vertex(0), t->get_vertex(1), t->get_vertex(2));
            t->set_flag(0);
            _edge_map.erase(_item);
            _item--;
        }
    }
    
}

void QuadMesh::add_edge(Triangle *t, int edge)
{
    Triangle *adj = t->get_adjacent(edge);
    
    double c0[2] = {t->get_center()[0], t->get_center()[1]};
    double c1[2] = {adj->get_center()[0], adj->get_center()[1]};
    
    double value = sqrtdist(c0, c1);
    _edge_map.insert(std::pair<double, std::pair<Triangle*, int> >(value, std::pair<Triangle*, int>(t, edge)));
}

void QuadMesh::export_vtk()
{
    static int count = 0;
    char filename[100];
    sprintf(filename, "test_quad_%d.vtk", count++);
    printf(" write file --> %s\n", filename);

    FILE *fp_rw = fopen (filename, "w");

    fprintf (fp_rw, "# vtk DataFile Version 2.0\n");
    fprintf (fp_rw, "Really cool data\n");
    fprintf (fp_rw, "ASCII\n");
    fprintf (fp_rw, "DATASET POLYDATA\n");
    fprintf (fp_rw, "POINTS %d float\n", (int)_tri->getVertexCount());

    for (int i = 0; i < _tri->getVertexCount(); i++)
        fprintf(fp_rw, "%lf %lf %lf\n", _tri->get_vertex(i)->p[0], _tri->get_vertex(i)->p[1], 0.0);

    fprintf (fp_rw, "POLYGONS %d %d\n", (int)_quad_list.size()+(int)_tri_list.size(), 5*(int)_quad_list.size()+4*(int)_tri_list.size());
    for (int i = 0; i < _quad_list.size(); i++)
    {
	Quad *q = _quad_list[i];
        fprintf(fp_rw, "%d %d %d %d %d\n", 4, q->get_vertex(0), q->get_vertex(1), q->get_vertex(2), q->get_vertex(3));
    }
    for (int i = 0; i < _tri_list.size(); i++)
    {
	Triangle *t = _tri_list[i];
        fprintf(fp_rw, "%d %d %d %d\n", 3, t->get_vertex(0), t->get_vertex(1), t->get_vertex(2));
    }
}
