// <summary>ソースコード：ＨＹＭＣＯビュー座標変換クラス</summary>
// <author>CommonMP</author>

using System;
using System.Collections.Generic;
using System.Text;

using CommonMP.HYSSOP.Interface;
using CommonMP.HYSSOP.Interface.HSData;
using CommonMP.HYSSOP.CoreImpl.HSData;
using CommonMP.HYMCO.Interface;

namespace CommonMP.HYMCO.CoreOptions.McViewer.DotNetViewer
{
    /// <summary><para>class outline:</para>
    /// <para>ビュー座標変換クラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2008/12/16][新規作成]</para>
    /// </remarks>
    public class McViewTransFormer : HySRoot
    {
        /// <summary><para>method outline:</para>
        /// <para>デフォルトコンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McViewTransFormer csTransFormer = new McViewTransFormer()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McViewTransFormer()
        {
        }

        /// <summary><para>method outline:</para>
        /// <para>画面表示座標変換</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ViewTrans(lDispScale, lBaseX, lBaseY, lDispX, lDispY)</para>
        /// </example>
        /// <param name="lDispScale">画面表示拡大率</param>
        /// <param name="lBaseX">ベース座標X（拡大率100%時）</param>
        /// <param name="lBaseY">ベース座標Y（拡大率100%時）</param>
        /// <param name="lDispX">画面表示座標X</param>
        /// <param name="lDispY">画面表示座標Y</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void ViewTrans(long lDispScale, long lBaseX, long lBaseY, ref long lDispX, ref long lDispY)
        {
            lDispX = lBaseX * lDispScale / 100;
            lDispY = lBaseY * lDispScale / 100;
        }

        /// <summary><para>method outline:</para>
        /// <para>画面表示座標変換（端子用）</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ViewTrans(SymbolDrawKind, lHeight, dRotate, lDispScale, lBaseX, lBaseY, lDispX, lDispY)</para>
        /// </example>
        /// <param name="SymbolDrawKind">シンボル描画種別</param>
        /// <param name="lHeight">要素サイズ(高さ)</param>
        /// <param name="dRotate">回転角度</param>
        /// <param name="lDispScale">画面表示拡大率</param>
        /// <param name="lBaseX">ベース座標X（拡大率100%時）</param>
        /// <param name="lBaseY">ベース座標Y（拡大率100%時）</param>
        /// <param name="lDispX">画面表示座標X</param>
        /// <param name="lDispY">画面表示座標Y</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void ViewTrans(McDefine.SymbolDrawKind SymbolDrawKind, long lHeight, double dRotate, long lDispScale, long lBaseX, long lBaseY, ref long lDispX, ref long lDispY)
        {
            if ((SymbolDrawKind != McDefine.SymbolDrawKind.HYM_RECEIVE) &&
                (SymbolDrawKind != McDefine.SymbolDrawKind.HYM_SEND) &&
                (SymbolDrawKind != McDefine.SymbolDrawKind.HYM_TRANS_IN) &&
                (SymbolDrawKind != McDefine.SymbolDrawKind.HYM_TRANS_OUT))
            {// 端子・中継端子以外の場合
                return;
            }

            //端子は親要素にデフォルト底面が接している事から端子サイズは高さのみ使用する。
            int iPortSize = (int)lHeight;
            int Offset = iPortSize * (int)lDispScale / 100 / 2 + 2 * (int)lDispScale / 100 - iPortSize / 2 - 2;

            if (dRotate == McDefine.HYM_DRAW_ANGLE_0)
            {// 向きが上の場合
                lDispX = lBaseX * lDispScale / 100;
                lDispY = lBaseY * lDispScale / 100 + Offset;
            }
            else if (dRotate == McDefine.HYM_DRAW_ANGLE_90)
            {// 向きが右の場合
                lDispX = lBaseX * lDispScale / 100 - Offset;
                lDispY = lBaseY * lDispScale / 100;
            }
            else if (dRotate == McDefine.HYM_DRAW_ANGLE_180)
            {// 向きが下の場合
                lDispX = lBaseX * lDispScale / 100;
                lDispY = lBaseY * lDispScale / 100 - Offset;
            }
            else if (dRotate == McDefine.HYM_DRAW_ANGLE_270)
            {// 向きが左の場合
                lDispX = lBaseX * lDispScale / 100 + Offset;
                lDispY = lBaseY * lDispScale / 100;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>端子配置座標変換</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>PortPotisionShift(lParentX, lParentY, lParentWidth, lParentHeight, dRotate, lPortHeight, lTotalPort, iPortNo, lPortX, lPortY)</para>
        /// </example>
        /// <param name="lParentX">親要素X（拡大率100%時）</param>
        /// <param name="lParentY">親要素Y（拡大率100%時）</param>
        /// <param name="lParentWidth">親要素幅（拡大率100%時）</param>
        /// <param name="lParentHeight">親要素高さ（拡大率100%時）</param>
        /// <param name="dRotate">回転角度</param>
        /// <param name="lPortHeight">端子高さ（拡大率100%時）</param>
        /// <param name="lTotalPort">端子数</param>
        /// <param name="iPortNo">端子番号</param>
        /// <param name="lPortX">端子配置座標X</param>
        /// <param name="lPortY">端子配置座標Y</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void PortPotisionShift(long lParentX, long lParentY, long lParentWidth, long lParentHeight, double dRotate, long lPortHeight, long lTotalPort, int iPortNo, ref long lPortX, ref long lPortY)
        {
            if (dRotate == McDefine.HYM_DRAW_ANGLE_0)
            {// 向きが上の場合
                lPortX = lParentX - lParentWidth / 2 + (lParentWidth / (lTotalPort + 1)) * (iPortNo + 1);
                lPortY = lParentY - lParentHeight / 2 - lPortHeight / 2 - 2;
            }
            else if (dRotate == McDefine.HYM_DRAW_ANGLE_90)
            {// 向きが右の場合
                lPortX = lParentX + lParentWidth / 2 + lPortHeight / 2 + 2;
                lPortY = lParentY - lParentHeight / 2 + (lParentHeight / (lTotalPort + 1)) * (iPortNo + 1);
            }
            else if (dRotate == McDefine.HYM_DRAW_ANGLE_180)
            {// 向きが下の場合
                lPortX = lParentX - lParentWidth / 2 + (lParentWidth / (lTotalPort + 1)) * (iPortNo + 1);
                lPortY = lParentY + lParentHeight / 2 + lPortHeight / 2 + 2;
            }
            else if (dRotate == McDefine.HYM_DRAW_ANGLE_270)
            {// 向きが左の場合
                lPortX = lParentX - lParentWidth / 2 - lPortHeight / 2 - 2;
                lPortY = lParentY - lParentHeight / 2 + (lParentHeight / (lTotalPort + 1)) * (iPortNo + 1);
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>ベース座標（モデル空間）変換</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>BaseTrans(lDispScale, lDispX, lDispY, lBaseX, lBaseY)</para>
        /// </example>
        /// <param name="lDispScale">画面表示拡大率</param>
        /// <param name="lDispX">画面表示座標X</param>
        /// <param name="lDispY">画面表示座標Y</param>
        /// <param name="lBaseX">ベース座標X（拡大率100%時）</param>
        /// <param name="lBaseY">ベース座標Y（拡大率100%時）</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void BaseTrans(long lDispScale, long lDispX, long lDispY, ref long lBaseX, ref long lBaseY)
        {
            lBaseX = lDispX * 100 / lDispScale;
            lBaseY = lDispY * 100 / lDispScale;
        }

        /// <summary><para>method outline:</para>
        /// <para>画面表示サイズ変換</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SizeTrans(lDispScale, SymbolDrawKind, iWidth, iHeight)</para>
        /// </example>
        /// <param name="lDispScale">画面表示拡大率</param>
        /// <param name="SymbolDrawKind">シンボル描画種別</param>
        /// <param name="iWidth">画面表示サイズ（幅）</param>
        /// <param name="iHeight">画面表示サイズ（高さ）</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void SizeTrans(long lDispScale, McDefine.SymbolDrawKind SymbolDrawKind, ref int iWidth, ref int iHeight)
        {
            if ((SymbolDrawKind != McDefine.SymbolDrawKind.HYM_RECEIVE) &&
                (SymbolDrawKind != McDefine.SymbolDrawKind.HYM_SEND))
            {// 端子以外の場合
                iWidth = iWidth * (int)lDispScale / 100;
                iHeight = iHeight * (int)lDispScale / 100;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>画面表示座標回転変換</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ViewRotateTrans(dRotate, lParentX, lParentY, lPortX, lPortY)</para>
        /// </example>
        /// <param name="dRotate">回転角度</param>
        /// <param name="lParentX">親要素表示座標X</param>
        /// <param name="lParentY">親要素表示座標Y</param>
        /// <param name="lPortX">端子表示座標X</param>
        /// <param name="lPortY">端子表示座標Y</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void ViewRotateTrans(double dRotate, long lParentX, long lParentY, ref long lPortX, ref long lPortY)
        {
            if (dRotate > 0)
            {// 回転角度が正方向の場合
                RotationClockwise90(lParentX, lParentY, ref lPortX, ref lPortY);
            }
            else
            {// 回転角度が負方向の場合
                RotationCounterclockwise90(lParentX, lParentY, ref lPortX, ref lPortY);
            }
        }
        
        /// <summary><para>method outline:</para>
        /// <para>時計回り９０度回転変換</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>RotationClockwise90(lElmX, lElmY, lPortX, lPortY)</para>
        /// </example>
        /// <param name="lElmX">要素中心座標X</param>
        /// <param name="lElmY">要素中心座標Y</param>
        /// <param name="lPortX">端子表示座標X</param>
        /// <param name="lPortY">端子表示座標Y</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>時計回り９０度回転 lElmX,lElmY = 要素中心座標、　lPortX,lPortY = 回転前端子Ｘ，Ｙ　＝＞回転の値、端子Ｘ，Ｙ</para>
        /// </remarks>
        static public void RotationClockwise90(long lElmX, long lElmY, ref long lPortX, ref long lPortY)
        {
            long lPortDltX = lPortX - lElmX;
            long lPortDltY = lPortY - lElmY;
            lPortX = -lPortDltY + lElmX;
            lPortY = lPortDltX + lElmY;
        }

        /// <summary><para>method outline:</para>
        /// <para>反時計周り９０度回転変換</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>RotationCounterclockwise90(lElmX, lElmY, lPortX, lPortY)</para>
        /// </example>
        /// <param name="lElmX">要素中心座標X</param>
        /// <param name="lElmY">要素中心座標Y</param>
        /// <param name="lPortX">端子表示座標X</param>
        /// <param name="lPortY">端子表示座標Y</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>反時計周り９０度回転 lElmX,lElmY = 要素中心座標、　lPortX,lPortY = 回転前端子Ｘ，Ｙ　＝＞回転の値、端子Ｘ，Ｙ</para>
        /// </remarks>
        static public void RotationCounterclockwise90(long lElmX, long lElmY, ref long lPortX, ref long lPortY)
        {
            long lPortDltX = lPortX - lElmX;
            long lPortDltY = lPortY - lElmY;
            lPortX = lPortDltY + lElmX;
            lPortY = -lPortDltX + lElmY;
        }

        /// <summary><para>method outline:</para>
        /// <para>端子移動座標計算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>PortPositionMove(iPointX, iPointY, lParentX, lParentY, lParentWidth, lParentHeight, lPortHeight, lPortX, lPortY, dRotate)</para>
        /// </example>
        /// <param name="iPointX">移動先指標座標X（拡大率100%時）</param>
        /// <param name="iPointY">移動先指標座標Y（拡大率100%時）</param>
        /// <param name="lParentX">親要素座標X（拡大率100%時）</param>
        /// <param name="lParentY">親要素座標Y（拡大率100%時）</param>
        /// <param name="lParentWidth">親要素幅（拡大率100%時）</param>
        /// <param name="lParentHeight">親要素高さ（拡大率100%時）</param>
        /// <param name="lPortHeight">端子高さ（拡大率100%時）</param>
        /// <param name="lPortX">端子座標X（拡大率100%時）</param>
        /// <param name="lPortY">端子座標X（拡大率100%時）</param>
        /// <param name="dRotate">端子回転角度</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void PortPositionMove(int iPointX, int iPointY, long lParentX, long lParentY, long lParentWidth, long lParentHeight, long lPortHeight, ref long lPortX, ref long lPortY, ref double dRotate)
        {
            long lParentLeftX = lParentX - lParentWidth / 2;
            long lParentTopY = lParentY - lParentHeight / 2;
            long lParentRightX = lParentX + lParentWidth / 2;
            long lParentBottomY = lParentY + lParentHeight / 2;

            if ((iPointX >= lParentLeftX) && (iPointY >= lParentTopY) && (iPointX <= lParentRightX) && (iPointY <= lParentBottomY))
            {// 移動先指標座標が要素上の場合
                return;
            }

            if ((iPointX >= lParentLeftX) &&
                (iPointX <= lParentRightX))
            {// 移動先指標座標が縦方向の場合
                lPortX = iPointX;

                if (iPointY <= lParentTopY)
                {// 移動先指標座標が上方向の場合
                    lPortY = lParentTopY - lPortHeight / 2 - 2;
                    dRotate = McDefine.HYM_DRAW_ANGLE_0;
                }
                else if (iPointY >= lParentBottomY)
                {// 移動先指標座標が下方向の場合
                    lPortY = lParentBottomY + lPortHeight / 2 + 2;
                    dRotate = McDefine.HYM_DRAW_ANGLE_180;
                }
            }
            else if ((iPointY >= lParentTopY) &&
                     (iPointY <= lParentBottomY))
            {// 移動先指標座標が横方向の場合
                lPortY = iPointY;

                if (iPointX <= lParentLeftX)
                {// 移動先指標座標が左方向の場合
                    lPortX = lParentLeftX - lPortHeight / 2 - 2;
                    dRotate = McDefine.HYM_DRAW_ANGLE_270;
                }
                else if (iPointX >= lParentRightX)
                {// 移動先指標座標が右方向の場合
                    lPortX = lParentRightX + lPortHeight / 2 + 2;
                    dRotate = McDefine.HYM_DRAW_ANGLE_90;
                }
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>グループシンボル座標計算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>GroupPositionCalc(csGroupElement, lX, lY)</para>
        /// </example>
        /// <param name="csGroupElement">グループ要素メンバーリスト</param>
        /// <param name="lX">グループシンボル座標X</param>
        /// <param name="lY">グループシンボル座標Y</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void GroupPositionCalc(List<McGraphicsElement> csGroupElement, ref long lX, ref long lY)
        {
            long lLeftTopX = 0;
            long lLeftTopY = 0;
            long lWorkX = 0;
            long lWorkY = 0;
            long lWidth = 0;
            long lHeight = 0;

            if (csGroupElement.Count <= 0)
            {// グループ要素メンバー数が０以下の場合
                return;
            }

            csGroupElement[0].GetPosition(ref lWorkX, ref lWorkY);

            if ((csGroupElement[0].GetRotate() == McDefine.HYM_DRAW_ANGLE_0) ||
                (csGroupElement[0].GetRotate() == McDefine.HYM_DRAW_ANGLE_180))
            {// 向きが上下の場合
                csGroupElement[0].GetElementSize(ref lWidth, ref lHeight);
            }
            else
            {// 向きが左右の場合
                csGroupElement[0].GetElementSize(ref lHeight, ref lWidth);
            }

            lLeftTopX = lWorkX - lWidth / 2;
            lLeftTopY = lWorkY - lHeight / 2;

            for (int iLp = 1; iLp < csGroupElement.Count; iLp++)
            {// グループ要素メンバー数ループ
                csGroupElement[iLp].GetPosition(ref lWorkX, ref lWorkY);

                if ((csGroupElement[iLp].GetRotate() == McDefine.HYM_DRAW_ANGLE_0) ||
                    (csGroupElement[iLp].GetRotate() == McDefine.HYM_DRAW_ANGLE_180))
                {// 向きが上下の場合
                    csGroupElement[iLp].GetElementSize(ref lWidth, ref lHeight);
                }
                else
                {// 向きが左右の場合
                    csGroupElement[iLp].GetElementSize(ref lHeight, ref lWidth);
                }

                if (lWorkX - lWidth / 2 < lLeftTopX)
                {// 最も左に位置する場合
                    lLeftTopX = lWorkX - lWidth / 2;
                }
                if (lWorkY - lHeight / 2 < lLeftTopY)
                {// 最も上に位置する場合
                    lLeftTopY = lWorkY - lHeight / 2;
                }
            }

            lX = lLeftTopX;
            lY = lLeftTopY;
        }

        /// <summary><para>method outline:</para>
        /// <para>グループ内要素設定座標チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>GroupMemberPosiCheck(csGroupElement, lMemberLeftX, lMemberTopY, lMemberRightX, lMemberBottomY)</para>
        /// </example>
        /// <param name="csGroupElement">グループ要素</param>
        /// <param name="lMemberLeftX">グループ内要素座標左X</param>
        /// <param name="lMemberTopY">グループ内要素座標上Y</param>
        /// <param name="lMemberRightX">グループ内要素座標右X</param>
        /// <param name="lMemberBottomY">グループ内要素座標下Y</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void GroupMemberPosiCheck(McGraphicsGroupElement csGroupElement, ref long lMemberLeftX, ref long lMemberTopY, ref long lMemberRightX, ref long lMemberBottomY)
        {
            long lTempWidth = 0;
            long lTempHeight = 0;
            long lTempX = 0;
            long lTempY = 0;

            lMemberLeftX = 0;
            lMemberTopY = 0;
            lMemberRightX = 0;
            lMemberBottomY = 0;

            if (csGroupElement.GetElmCount() == 0)
            {// グループ内要素が０以下の場合
                return;
            }

            csGroupElement.GetElement(0).GetPosition(ref lTempX, ref lTempY);
            if ((csGroupElement.GetElement(0).GetRotate() == McDefine.HYM_DRAW_ANGLE_0) ||
                (csGroupElement.GetElement(0).GetRotate() == McDefine.HYM_DRAW_ANGLE_180))
            {// 向きが上下の場合
                csGroupElement.GetElement(0).GetElementSize(ref lTempWidth, ref lTempHeight);
            }
            else
            {// 向きが左右の場合
                csGroupElement.GetElement(0).GetElementSize(ref lTempHeight, ref lTempWidth);
            }
            lMemberLeftX = lTempX - lTempWidth / 2;
            lMemberTopY = lTempY - lTempHeight / 2;
            lMemberRightX = lTempX + lTempWidth / 2;
            lMemberBottomY = lTempY + lTempHeight / 2;

            for (int iLp = 1; iLp < csGroupElement.GetElmCount(); iLp++)
            {// グループ内要素数ループ
                csGroupElement.GetElement(iLp).GetPosition(ref lTempX, ref lTempY);
                if ((csGroupElement.GetElement(iLp).GetRotate() == McDefine.HYM_DRAW_ANGLE_0) ||
                    (csGroupElement.GetElement(iLp).GetRotate() == McDefine.HYM_DRAW_ANGLE_180))
                {// 向きが上下の場合
                    csGroupElement.GetElement(iLp).GetElementSize(ref lTempWidth, ref lTempHeight);
                }
                else
                {// 向きが左右の場合
                    csGroupElement.GetElement(iLp).GetElementSize(ref lTempHeight, ref lTempWidth);
                }

                if (lMemberLeftX > lTempX - lTempWidth / 2)
                {// 最も左に位置する場合
                    lMemberLeftX = lTempX - lTempWidth / 2;
                }
                if (lMemberTopY > lTempY - lTempHeight / 2)
                {// 最も上に位置する場合
                    lMemberTopY = lTempY - lTempHeight / 2;
                }
                if (lMemberRightX < lTempX + lTempWidth / 2)
                {// 最も右に位置する場合
                    lMemberRightX = lTempX + lTempWidth / 2;
                }
                if (lMemberBottomY < lTempY + lTempHeight / 2)
                {// 最も下に位置する場合
                    lMemberBottomY = lTempY + lTempHeight / 2;
                }
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>貼り付けシンボル最小X・Y座標チェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>PasteMinimumXYCheck(csPasteElmList, lX, lY)</para>
        /// </example>
        /// <param name="csPasteElmList">貼り付けシンボルリスト</param>
        /// <param name="lX">最小X座標</param>
        /// <param name="lY">最小Y座標</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void PasteMinimumXYCheck(HySDataLinkedList csPasteElmList, ref long lX, ref long lY)
        {
            long lLeftTopX = -1;
            long lLeftTopY = -1;
            long lWorkX = 0;
            long lWorkY = 0;

            for (int iLp = 0; iLp < csPasteElmList.GetCount(); iLp++)
            {// 貼り付けシンボル数ループ
                if (((McGraphicsElement)csPasteElmList.GetData(iLp)).GetSymbolDrawKind() != McDefine.SymbolDrawKind.HYM_LINE)
                {// 接続線以外の場合
                    ((McGraphicsElement)csPasteElmList.GetData(iLp)).GetPosition(ref lWorkX, ref lWorkY);

                    if ((lLeftTopX == -1) || (lWorkX < lLeftTopX))
                    {// 最も左に位置する場合
                        lLeftTopX = lWorkX;
                    }
                    if ((lLeftTopY == -1) || (lWorkY < lLeftTopY))
                    {// 最も上に位置する場合
                        lLeftTopY = lWorkY;
                    }
                }
            }

            lX = lLeftTopX;
            lY = lLeftTopY;
        }

        /// <summary><para>method outline:</para>
        /// <para>プロジェクト中心座標計算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ProjectCenterPositionCalc(csProjectElement, lX, lY)</para>
        /// </example>
        /// <param name="csProjectElement">プロジェクト要素メンバーリスト</param>
        /// <param name="lX">プロジェクト中心座標X</param>
        /// <param name="lY">プロジェクト中心座標Y</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void ProjectCenterPositionCalc(List<McGraphicsElement> csProjectElement, ref long lX, ref long lY)
        {
            long lTempWidth = 0;
            long lTempHeight = 0;
            long lTempX = 0;
            long lTempY = 0;

            long lMemberLeftX = 0;
            long lMemberTopY = 0;
            long lMemberRightX = 0;
            long lMemberBottomY = 0;

            if (csProjectElement.Count == 0)
            {// プロジェクト要素メンバー数が０の場合
                return;
            }

            csProjectElement[0].GetPosition(ref lTempX, ref lTempY);
            if ((csProjectElement[0].GetRotate() == McDefine.HYM_DRAW_ANGLE_0) ||
                (csProjectElement[0].GetRotate() == McDefine.HYM_DRAW_ANGLE_180))
            {// 向きが上下の場合
                csProjectElement[0].GetElementSize(ref lTempWidth, ref lTempHeight);
            }
            else
            {// 向きが左右の場合
                csProjectElement[0].GetElementSize(ref lTempHeight, ref lTempWidth);
            }
            lMemberLeftX = lTempX - lTempWidth / 2;
            lMemberTopY = lTempY - lTempHeight / 2;
            lMemberRightX = lTempX + lTempWidth / 2;
            lMemberBottomY = lTempY + lTempHeight / 2;

            for (int iLp = 1; iLp < csProjectElement.Count; iLp++)
            {// プロジェクト要素メンバー数ループ
                csProjectElement[iLp].GetPosition(ref lTempX, ref lTempY);
                if ((csProjectElement[iLp].GetRotate() == McDefine.HYM_DRAW_ANGLE_0) ||
                    (csProjectElement[iLp].GetRotate() == McDefine.HYM_DRAW_ANGLE_180))
                {// 向きが上下の場合
                    csProjectElement[iLp].GetElementSize(ref lTempWidth, ref lTempHeight);
                }
                else
                {// 向きが左右の場合
                    csProjectElement[iLp].GetElementSize(ref lTempHeight, ref lTempWidth);
                }

                if (lMemberLeftX > lTempX - lTempWidth / 2)
                {// 最も左に位置する場合
                    lMemberLeftX = lTempX - lTempWidth / 2;
                }
                if (lMemberTopY > lTempY - lTempHeight / 2)
                {// 最も上に位置する場合
                    lMemberTopY = lTempY - lTempHeight / 2;
                }
                if (lMemberRightX < lTempX + lTempWidth / 2)
                {// 最も右に位置する場合
                    lMemberRightX = lTempX + lTempWidth / 2;
                }
                if (lMemberBottomY < lTempY + lTempHeight / 2)
                {// 最も下に位置する場合
                    lMemberBottomY = lTempY + lTempHeight / 2;
                }
            }

            lX = lMemberLeftX + (lMemberRightX - lMemberLeftX) / 2;
            lY = lMemberTopY + (lMemberBottomY - lMemberTopY) / 2;
        }

        /// <summary><para>method outline:</para>
        /// <para>選択要素全体を左に90度回転</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>AllLeft90degRotation(csProjectElement, lX, lY)</para>
        /// </example>
        /// <param name="lRX">中心座標X</param>
        /// <param name="lRY">中心座標Y</param>
        /// <param name="lX">要素座標X</param>
        /// <param name="lY">要素座標Y</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void AllLeft90degRotation(long lRX, long lRY, ref long lX, ref long lY)
        {
            long lAX = lX - lRX;
            long lAY = lY - lRY;

            long lAX2 = lAY;
            long lAY2 = -lAX;

            lX = lAX2 + lRX;
            lY = lAY2 + lRY;
        }


        /// <summary><para>method outline:</para>
        /// <para>選択要素全体を右に90度回転</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>AllRight90degRotation(csProjectElement, lX, lY)</para>
        /// </example>
        /// <param name="lRX">中心座標X</param>
        /// <param name="lRY">中心座標Y</param>
        /// <param name="lX">要素座標X</param>
        /// <param name="lY">要素座標Y</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        static public void AllRight90degRotation(long lRX, long lRY, ref long lX, ref long lY)
        {
            long lAX = lX - lRX;
            long lAY = lY - lRY;

            long lAX2 = -lAY;
            long lAY2 = lAX;

            lX = lAX2 + lRX;
            lY = lAY2 + lRY;
        }
    }
}
