#include "MGCLStdAfx.h"
#include "mg/BezierMove.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//反対側の方向線の移動(点対象)
void moveOppositeControlPoint_reflect(
	MGBPointSeq& bp,
	int center_idx,
	int move_idx,
	MGPosition new_move_point,
	bool bClose
){
	int npm1=bp.length()-1;
	int oppo_idx = 2 * center_idx - move_idx;//反対側の点のインデックス
	if(oppo_idx < 0 || oppo_idx > npm1)
		if(bClose)
			oppo_idx = oppo_idx<0 ? oppo_idx+npm1 : oppo_idx-npm1;
		else
			return;

	MGVector diff = bp(center_idx) - bp(move_idx);
	if(diff.is_zero_vector())
		return;
	bp.store_at(oppo_idx, diff + bp(center_idx));
}

MGBezierMove::MGBezierMove(
	const MGLBRep& bezier,
	bool Divide,
	double t_pivot
):m_originalBezier(bezier),m_divide(Divide),m_pivot(t_pivot),
m_pivotP(bezier.eval(t_pivot)
){
	assert(bezier.is_Bezier(4));
	m_closed=bezier.is_closed();
	const MGKnotVector& t=bezier.knot_vector();
	m_index=t.locate(m_pivot)-3;
	
	//m_bIsParallel_s, m_bIsParallel_eの初期化
	m_bIsParallel_s = isParallel(bezier.line_bcoef(), m_index);
	m_bIsParallel_e = isParallel(bezier.line_bcoef(), m_index+3);
}

//つまみ変形
void MGBezierMove::movePoint(
	const MGPosition& ToPoint,
	MGLBRep& mevedBezier
){
	//移動の計算
	MGVector diff = ToPoint - m_pivotP;
	
	//元の曲線の点列
	const MGBPointSeq& ori_bp = m_originalBezier.line_bcoef();
	mevedBezier=m_originalBezier;

	//一時描画の曲線の点列
	MGBPointSeq& tmp_bp = mevedBezier.line_bcoef();
	if(m_divide){
		m_bIsParallel_s=m_bIsParallel_e=false;//ここでは一度折れたら復活させない
	}


	//始点側を方向線移動
	int idp1=m_index+1;
	tmp_bp.store_at(idp1, ori_bp(idp1)+diff);
	if(m_bIsParallel_s)
		moveOppositeControlPoint_reflect(tmp_bp, m_index, idp1, ori_bp(idp1)+diff, m_closed);

	//終点側を方向線移動
	int idp2=m_index+2;
	tmp_bp.store_at(idp2,  ori_bp(idp2) + diff);
	if(m_bIsParallel_e)
		moveOppositeControlPoint_reflect(tmp_bp, m_index+3, idp2, ori_bp(idp2)+diff, m_closed);
}

//与えられたknotの前後の方向線が平行かチェック
bool MGBezierMove::isParallel(const MGBPointSeq& bp, int index){
	if((index <= 0 || index >= bp.length() - 1))
		//indexの前後に点が無い
		return false;

	return (bp(index-1)-bp(index)).parallel(bp(index+1)-bp(index));
}
