// == LICENSE INFORMATION ==
/*
 * First author tiritomato 2013.
 * This program is distributed under the GNU General Public License(GPL).
 * support blog (Japanese only) http://d.hatena.ne.jp/tiri_tomato/
 */
// == LICENSE INFORMATION ==

namespace UVTexIntegra.CustomControls
{
    public static partial class Drawing
    {
        public struct Edge {

            //! @brief 辺の端を取得します。X要素の小さい方がBeginPointになります。
            public OpenTK.Vector2 BeginPoint { get { return m_beginPt; } }
            //! @brief 辺の端の色を取得します。BeginPoint側の色を取得します。
            public System.Drawing.Color BeginPointColor { get { return m_beginPtC; } }
            //! @brief 辺の端を取得します。X要素の大きい方がEndPointになります。
            public OpenTK.Vector2 EndPoint { get { return m_endPt; } }
            //! @brief 辺の端の色を取得します。EndPoint側の色を取得します。
            public System.Drawing.Color EndPointColor { get { return m_endPtC; } }
            //! @brief この面を所有する三角形の重心を取得します。
            //! @details @attention この情報はOwnerCountが１の時だけ信頼できます。複数の三角形に共有される辺の場合はオーナー三角形が一意に定まりません。
            public OpenTK.Vector2 OwnerGravity { get { return m_ownerGravity; } }
            //! @brief 共有される数を取得します。
            //! @details このインクリメントはOwnerInc()メソッドで行います。インクリメントはFaceBufferクラスに面を追加する時、Edgeリストの構築を行っており、
            //! FaceBufferクラスに過去に同じEdge要素が登録されていれば、Edgeリストを新規追加せず、共有数のインクリメントを行います。
            public int OwnerCount { get { return m_ownerCt; } }

            public Edge(ref OpenTK.Vector2 beginPt, System.Drawing.Color beginPtColor,
                ref OpenTK.Vector2 endPt, System.Drawing.Color endPtColor,  ref OpenTK.Vector2 g)
            {
                m_beginPt = beginPt;
                m_beginPtC = beginPtColor;
                m_endPt = endPt;
                m_endPtC = endPtColor;
                m_ownerGravity = g;
                m_ownerCt = 1;
                OrderSort();
            }

            public bool Equals(ref OpenTK.Vector2 beginPoint, ref OpenTK.Vector2 endPoint, float epsilon)
            {
                if (beginPoint.X < endPoint.X)
                {
                    return (System.Math.Abs(m_beginPt.X - beginPoint.X) <= epsilon)
                        && (System.Math.Abs(m_beginPt.Y - beginPoint.Y) <= epsilon)
                        && (System.Math.Abs(m_endPt.X - endPoint.X) <= epsilon)
                        && (System.Math.Abs(m_endPt.Y - endPoint.Y) <= epsilon);
                }
                return (System.Math.Abs(m_endPt.X - beginPoint.X) <= epsilon)
                    && (System.Math.Abs(m_endPt.Y - beginPoint.Y) <= epsilon)
                    && (System.Math.Abs(m_beginPt.X - endPoint.X) <= epsilon)
                    && (System.Math.Abs(m_beginPt.Y - endPoint.Y) <= epsilon);
            }

            public int OwnerInc() { return ++m_ownerCt; }

            private OpenTK.Vector2 m_beginPt, m_endPt, m_ownerGravity;
            private System.Drawing.Color m_beginPtC, m_endPtC;
            private int m_ownerCt;

            private void OrderSort()
            {
                if (m_beginPt.X < m_endPt.X)
                {
                    OpenTK.Vector2 tmpPt = m_beginPt;
                    System.Drawing.Color tmpPtC = m_beginPtC;
                    m_beginPt = m_endPt;
                    m_beginPtC = m_endPtC;
                    m_endPt = tmpPt;
                    m_endPtC = tmpPtC;
                }
            }

            private static void OrderSort(ref OpenTK.Vector2 pt1, ref OpenTK.Vector2 pt2)
            {
                if (pt1.X < pt2.X)
                {
                    OpenTK.Vector2 tmp = pt1;
                    pt1 = pt2;
                    pt2 = pt1;
                }
            }
        }

        static int GetRegistedEdgeIndex(this System.Collections.Generic.List<Edge> src, ref OpenTK.Vector2 beginPoint, ref OpenTK.Vector2 endPoint, float epsilon)
        {
            if (src != null) for (int index = 0; index < src.Count; index++)
                if (src[index].Equals(ref beginPoint, ref endPoint, epsilon)) return index;
            return -1;
        }

    }
}
