//
//  Mesh.h
//  prog2
//
//  Created by Neil Killeen on 5/15/13.
//  Copyright (c) 2013 Neil Killeen. All rights reserved.
//

#ifndef __prog2__Mesh__
#define __prog2__Mesh__

#include "Angel.h"
#include <map>
#include <vector>
#include <iostream>

using namespace Angel;

typedef vec3 point3, color3;
typedef vec4 point4, color4;

struct  MapComparator {
    bool operator()(const vec3& lhs, const vec3& rhs) const {
        if (lhs.x < rhs.x) return true;
        if (lhs.x > rhs.x) return false;
        if (lhs.y < rhs.y) return true;
        if (lhs.y > rhs.y) return false;
        if (lhs.z < rhs.z) return true;
        return false;
    }
};

class polygon {
public:
    std::vector<GLuint> indices;
    vec3 normal;
};

class Mesh {
public:
    std::map<point3, std::vector<vec3>,  MapComparator> VertexMap;
    std::vector<point4> allVertices;
    std::vector<vec3> allNormals;
    std::vector<polygon> allPolys;
    
    Mesh();
    
    void draw(const GLuint &vPos, const GLuint &vNormal, GLuint &ModelView, int SEL_ID, bool solid = true);
    
    // Model transformations (These directly modify model input)
    void vRotate(GLfloat x, GLfloat y, GLfloat z);
    void vScale(GLfloat x, GLfloat y, GLfloat z);
    void vTranslate(GLfloat x, GLfloat y, GLfloat z);
    
    // Model transformations (These modify model view)
    void mRotate(GLfloat x, GLfloat y, GLfloat z);
    void mScale(GLfloat x, GLfloat y, GLfloat z);
    void mTranslate(GLfloat x, GLfloat y, GLfloat z);

    void calcNormals();
    void readVertices(const char *filename);
    void readPolygons(const char *filename);
    
    void addNormal(const point3& pt1, const point3& pt2, const point3& pt3, const vec3& normal);
    void addVertex(const point3& point);
    void addVertex(const point4& point);
    
    mat4& getModelView() { return m_view; }
    vec3 getModelCenter() const { return m_center; }
    void setSelectColor(const color4 &that) { m_sel_color = that; }
    void setColor(const color4 &that) { m_color = that; }
    
private:    
    mat4 m_view;
    vec4 m_color;
    vec4 m_sel_color;
    vec3 m_center;
    
    GLfloat m_pitch;
    GLfloat m_yaw;
    GLfloat m_roll;
    
    bool highlight;
    
    vec3 calcNormal(const point3& vertex) const;
};

#endif /* defined(__prog2__Mesh__) */
