/*
  Maze editor: 3D model class
  Copyright (C) 1998 by Jorrit Tyberghein
  Written by Andrew Zabolotny <bit@eltech.ru>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free
  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __ME_POLY_H__
#define __ME_POLY_H__

#include "csutil/csbase.h"


class mz3DModel;

/// Maximum allowed vertices in a polygon
#define MAX_POLYGON_VERTICES 16

/// Polygon error codes
enum csPolyError
{
  /// Polygon is okay
  cspeOK,
  /// Polygon does not have enough vertices
  cspeUnderflow,
  /// Polygon has more than MAX_POLYGON_VERTICES vertices
  cspeOverflow,
  /// Polygon has some vertex included more than once
  cspeDuplicateVertex,
  /// Polygon has no parent model
  cspeNoParent,
  /// Polygon vertices are not coplanar
  cspeNonCoplanar,
  /// Polygon is not convex
  cspeNonConvex
};

/**
 * This class represents a polygon of the 3D model.<p>
 * It contains a list of indexes into parent model object's Vertex
 * array; that is, mz3DPolygon's Vertex array contains just the indices of
 * corresponding mz3DVector objects in parent model's Vertex array.
 */
class mz3DPolygon : public csObject
{
  /// The vertices that form this polygon
  csVector V;

public:
  /// Polygon is selected?
  bool selected;
  /// Parent model
  mz3DModel *parent;
  /// Polygon color (one of cs_Color_XXX) or -1 for default
  int Color;
  /// Polygon name (initially automatically generated)
  char *Name;

  /// Whether this polygon will mirror the room or not
  bool mirror;

  /// alpha transparancy 
  float alpha;

/// sector this polygon belong to
  csSector* sector;

  /// Texture used for this polygon
  csTextureHandle *Texture;

  /// Portal for this polygon (NULL if none)
  char *portal;

  /// Space warp matrix (if any)
  csReversibleTransform *SpaceWarp;

  /// corresponding csPolygon3D counterpart
  csPolygon3D *csp;

  /// Initialize the polygon object
  mz3DPolygon (mz3DModel *iParent);

  /// Copy constructor
  mz3DPolygon (mz3DPolygon &iCopy);

  /// Destructor
  virtual ~mz3DPolygon ();

  /// Get a reference to vertex iVertex
  inline int& operator [] (int iVertex)
  { return (int&)V [iVertex]; }

  /// Get a reference to vertex by index into this polygon
  mz3DVertex& Vertex (int iVertex);

  /// Get number of vertices in polygon
  inline int Vertices () const
  { return V.Length (); }

  /**
   * This method is called to notify polygon that a vertex has been deleted
   * from parent model. Polygon should re-scan its Vertex array upon reception
   * of this model and decrement indices of all vertices which's indices are
   * above index of the vertex that has been deleted. If polygon contains
   * deleted vertex, it should be deleted too and returns "false".
   */
  bool NotifyVertexDeleted (int iVertex);

  /// Compare two polygons for equality
  bool operator == (const mz3DPolygon &p) const;

  /// Check polygon for correctness and return error code
  csPolyError Check ();

  /// Return a descriptive string for given error code or NULL
  char *ErrorText (csPolyError iCode);

  /// Set name of this polygon
  void SetName (const char *iName);

  /// Delete a vertex
  void DeleteVertex (int iVertex)
  { V.Delete (iVertex); }

  /// Reverse polygon's visible side
  void Reverse ();
};

#endif // __ME_POLY_H__
