/***************************************************************************
 *                          Zanoza Modeler v2.x                            *
 *      This is unpublished propietary source code of Zanoza Software.     *
 *      The copyright notice does not evidence any actual or intended      *
 *                    publication of such source code.                     *
 *                                                                         *
 *                Copyright (c) 2002-2003 Zanoza Software.                 *
 *                                                                         *
 *                        All rights reserved.                             *
 ***************************************************************************
 *--------------------------------------------------------------------------
 * @author:   Oleg M.
 *--------------------------------------------------------------------------
 * @purpose:  open edges helper
 *--------------------------------------------------------------------------
 * @histroy: 19.11.2004. Created
 */
#ifndef openedgeshelper_h_included
#define openedgeshelper_h_included

#include <zmodeler.h>

namespace core
{
  namespace tools
  {
    //
    // helper
    //
    struct DLL_LINKAGE tEdge
    {
      tEdge()
      {
        i1 = i2 = 0;
        count = 1;
      }
      tEdge(WORD _1, WORD _2)
      {
        i1 = _1; i2 = _2; count = 1;
      }
      WORD  i1, i2; //from i1 to i2;
      WORD  count;
      bool operator == (const tEdge& edge)
      {
        return  i1 == edge.i1 && i2 == edge.i2 ||
                i1 == edge.i2 && i2 == edge.i1;
      }
      bool match(const tEdge& edge)
      {
        if (i1 == edge.i1 && i2 == edge.i2 || i1 == edge.i2 && i2 == edge.i1)
        {
          count++;
          return true;
        }
        else
          return false;
      }
      tEdge& setTo(const WORD _1, const WORD _2)
      {
        i1 = _1;
        i2 = _2;
        count = 1;
        return *this;
      }
      inline void flip()
      {
        WORD i = i1;
        i1 = i2;
        i2 = i;
      }
      inline void flip(tEdge& edge)
      {
        WORD i = i1;
        i1 = edge.i2;
        edge.i2 = i;
        i = i2;
        i2 = edge.i1;
        edge.i1 = i;
      }
      // returns true if edge chains us. if required, supplied edge is reoriented
      bool chain(tEdge& edge)
      {
        if (i2 == edge.i1)
          return true;
        else
          if (i2 == edge.i2)
          {
            edge.i2 = edge.i1;
            edge.i1 = i2;
            return true;
          }
        return false;
      }
      // returns true if we chains supplied edge
      bool revChain(tEdge& edge)
      {
        if (i1 == edge.i2)
          return true;
        else
          if (i1 == edge.i1)
          {
            edge.i1 = edge.i2;
            edge.i2 = i1;
            return true;
          }
        return false;
      }
    };//tEdge
    typedef ZSequence<tEdge>    tChain, tEdgeList;

    //-------------------------------------------------------
    // @name : ZAPICALL detectOpenEdges
    // Comment  
    // @param VertexBuf& vBuf                : 
    // @param ZPolyBuf& pBuf                 : 
    // @param tEdgeList& list                : 
    // @param DWORD dwVertHasStatus          : 
    // @param DWORD dwVertHasntStatus        : 
    //
    // @return DLL_LINKAGE ZRESULT : 
    //-------------------------------------------------------
    DLL_LINKAGE ZRESULT ZAPICALL detectOpenEdges(
                          ZVertexBuf& vBuf, 
                          ZPolyBuf& pBuf, 
                          tEdgeList& list,
                          DWORD dwVertHasStatus = STATUS_SELECTED | STATUS_ENABLED,
                          DWORD dwVertHasntStatus = STATUS_HIDDEN);
    //-------------------------------------------------------
    // @name : ZAPICALL getChain
    // extracts chain of vertices from list;
    // @param tEdgeList& list                : 
    // @param tChain& chain                  : 
    //
    // @return DLL_LINKAGE bool : 
    //-------------------------------------------------------
    DLL_LINKAGE bool ZAPICALL extractMaxChain(tEdgeList& list, tChain& chain);

    //-------------------------------------------------------
    // @name : ZAPICALL extractMaxChainWithItem
    // Extracts maximum chain with supplied item
    // @param tEdgeList& list                : 
    // @param tChain& chain                  : 
    // @param long nItem                     : 
    //
    // @return DLL_LINKAGE bool : 
    //-------------------------------------------------------
    DLL_LINKAGE bool ZAPICALL extractMaxChainWithItem(tEdgeList& list, tChain& chain, long nItem);

    //-------------------------------------------------------
    // @name : ZAPICALL reorderChain
    // back-orders chain
    // @param tChain& chain                  : 
    //
    // @return DLL_LINKAGE void : 
    //-------------------------------------------------------
    DLL_LINKAGE void ZAPICALL reorderChain(tChain& chain);
    inline WORD getVertexIndex(tChain& chain, float f)
    {
      long indx = INT((chain.length()-1)*f);
      return f >= 0.5f ? chain[indx].i2 : chain[indx].i1;
    }

  };//tools
};//core

#endif //openedgeshelper_h_included

