//
//	点移動
//
function private _MoveVertex()
{
	var point_temp[2];
	var prev, v, cur_vec, cur_map[2];
	var prev_sel, sel;
	var i, j, vers, key, temp;
	var edge;
	var pick, draw_flag = ON, plane[3];

	prev = Cursor();
	if (prev != PolyVertex( prev ))
	{
		Warning();
		if( MESSAGE == ON )
			Message( error_msg1 );
		return ;
	}

	prev_sel = Select();
	if(( ShiftStat() & 1 ) == 1 )
	{
		if( SelectPolygons() == 0 )
			SelectAll( TRUE );
	}
	else
		SelectAll( TRUE );
	SelectArea( TRUE, SELECT_AND | SELECT_SUB, prev, prev );
	if( SelectPolygons() == 0 )
	{
		Warning();
		Select( prev_sel );
		return;
	}
	sel = Select();
	edge = EdgeSelect();
	edge = EdgeVertex( edge, prev );
	Select( prev_sel );

	PushMenu();
	Status_org = Status_title;
	MenuPosition( Menu( " 動作設定(&S)",
			"移動中止	ESC",	MenuQuit
		), Menu_Title );
	ClearStatus();
	Status_title[0] = "【点移動中】";
	DrawStatus();
	quit_flag = FALSE;

	j = Edges( edge );
	PolyLoadInit();
	PolyLoad();
	plane[0] = PolyGetVertex(0);
	for( i = 1;i< PolyVertexs();i++ )
	{
		plane[1] = PolyGetVertex(i);
		if( plane[0] != plane[1] )
			break;
	}
	temp = Position( plane[1] ) - Position( plane[0] );
	for( i++; i< PolyVertexs(); i++ )
	{
		plane[2] = PolyGetVertex(i);
		if( abs((Position(plane[2])-Position(plane[0]))*temp) != 0 )
			break;
	}
	cur = prev;
	pick = cur;
	fix_vertex = cur;
	input_flag = OFF;
	while( TRUE )
	{
		if( draw_flag == ON )
		{
			for( i = 0;i<j; i++ )
			{
				EdgeGetVertex( edge, i, point_temp );
				if( point_temp[0] == prev )
					DrawLine( point_temp[1], cur );
				else
					DrawLine( point_temp[0], cur );
			}
		}
		key = WaitEvent();
		if( key )
			input_flag = ON;
		if( ( ShiftStat() & 1 ) == 1 )
		{
			cur = Cursor();
			TrimCursor(fix_vertex, MouseWindow());
			Cursor( cur );
		}
		else
			cur = Cursor();
		key = KeyCode();
		if( input_flag | key == INPUT_KEY )
		{
			if( prev == cur )
			{
				Warning();
				if( MESSAGE == ON )
					Message( error_msg5 );
			}
			else
				break;
		}
		else if ( key == ESC | quit_flag == TRUE )
		{
			PopandClear( OVERWRITE );
			Select( prev_sel );
			return ;
		}
		else if ( key == BS )
		{
			if( cur == prev )
			{
				PopandClear( OVERWRITE );
				Select( prev_sel );
				return;
			}
			else
			{
				cur = prev;
				fix_vertex = cur;
				Cursor( cur );
			}
		}
		else if ( key == 'p' )
		{
			cur = PolyPlane( cur, MouseWindow(),
					plane[0], plane[1], plane[2] );
			Cursor( cur );
		}
		else
			temp = KeyProcess( key );
		if( ((key!=0 ) & (key != INPUT_KEY)) | ( pick != Cursor()) )
		{
			for( i = 0;i<j; i++ )
			{
				EdgeGetVertex( edge, i, point_temp );
				if( point_temp[0] == prev )
					DrawLine( point_temp[1], pick );
				else
					DrawLine( point_temp[0], pick );
			}
			draw_flag = ON;
		}
		else
			draw_flag = OFF;
		pick = Cursor();
		input_flag = OFF;
	}
	Clear( OVERWRITE );
	Select( sel );
	v = Position( cur )- Position(prev);
	PolyLoadInit();
	while( PolyLoad())
	{
		vers = PolyVertexs();
		for( i = 0;i<vers;i++ )
		{
			temp = PolyGetVertex( i );
			if( temp == prev )
				PolySetVertex( temp+v, i );
		}
		PolySave();
	}
	Select( prev_sel );
	Update( CLEAR );
	UpdateObject();
	pers_rotation_flag = FALSE;
	PopMenu();
	Status_title = Status_org;
	DrawStatus();
}

//
//	点追加
//
function private _AddVertex()
{
	var point[2], prev, prev2;
	var prev_sel, work_sel, plane[3];
	var cur_pos;
	var i, j, k, vers, key, ty, flag;
	var temp, temp2, temp_vec, temp2_vec, temp_map[2], temp2_map[2];
	var pick, draw_flag = ON;
	var edge;

	prev = Cursor();
	if (prev != PolyVertex( prev ))
	{
		Warning();
		if( MESSAGE == ON )
			Message( error_msg1 );
		return ;
	}

	prev_sel = Select();
	if( ( ShiftStat() & 1 ) == 1 )
	{
		if( SelectPolygons() == 0 )
			SelectAll( TRUE );
	}
	else
		SelectAll( TRUE );
	SelectArea( TRUE, SELECT_AND | SELECT_SUB, prev, prev );
	if( SelectPolygons() == 0 )
	{
		Warning();
		Select( prev_sel );
		return;
	}
	work_sel = Select();

	PushMenu();
	Status_org = Status_title;
	MenuPosition( Menu( " 動作設定(&S)",
			"追加中止	ESC", MenuQuit ), Menu_Title );
	ClearStatus();
	Status_title[0] = "【点追加する辺を指定中】";
	DrawStatus();
	quit_flag = FALSE;

	edge = EdgeSelect();
	edge = EdgeVertex( edge, prev );
	j = Edges( edge );
	Select( prev_sel );

	PolyLoadInit();
	PolyLoad();
	plane[0] = PolyGetVertex(0);
	for( i = 1;i< PolyVertexs();i++ )
	{
		plane[1] = PolyGetVertex(i);
		if( plane[0] != plane[1] )
			break;
	}
	temp = Position( plane[1] ) - Position( plane[0] );
	for( i++; i< PolyVertexs(); i++ )
	{
		plane[2] = PolyGetVertex(i);
		if( abs((Position(plane[2])-Position(plane[0]))*temp) != 0 )
			break;
	}

	k = 0;
	cur = prev;
	pick = cur;
	fix_vertex = cur;
	flag = FALSE;
	while( TRUE )
	{
		input_flag = OFF;
		while( TRUE )
		{
			if( draw_flag == ON )
			{
				if( flag == FALSE )
					DrawLine( cur, prev );
				else
				{
					DrawLine( cur, prev );
					DrawLine( cur, prev2 );
				}
			}
			key = WaitEvent();
			if( key )
				input_flag = ON;
			if( ( ShiftStat() & 1 ) == 1 )
			{
				cur = Cursor();
				TrimCursor(fix_vertex, MouseWindow());
				Cursor( cur );
			}
			else
				cur = Cursor();
			key = KeyCode();
			if ( input_flag | key == INPUT_KEY )
			{
				if( flag == FALSE )
				{
					if ( prev == cur )
					{
						Warning();
						if( MESSAGE == ON )
							Message( error_msg4 );
					}
					else
					{
						if( Edges(EdgeVertex( edge, cur )) != 0 )
						{
							Select( work_sel );
							EdgeSelect(EdgeVertex( edge, cur ), TRUE, SELECT_AND );
							if( MESSAGE == ON )
								Message( "指定された辺の真ん中に点を追加しました\n"
									+"続いて、この点を移動させることができます" );
							Status_title[0] = "【点移動中】";
							DrawStatus();
							work_sel = Select();
							Select( prev_sel );
							break;
						}
						else
						{
							Warning();
							if( MESSAGE == ON )
								Message( "点を追加する辺を指定してください" );
						}
					}
				}
				else
				{
					if( cur == prev | cur == prev2 )
					{
						Warning();
						if( MESSAGE == ON )
							Message( "指定した辺の端点と同じ点です" );
					}
					else
						break;
				}
			}
			else if ( key == ESC | quit_flag == TRUE )
			{
				PopandClear( OVERWRITE );
				Select( prev_sel );
				return ;
			}
			else if ( key == BS )
			{
				if( flag == FALSE )
				{
					if( cur == prev )
					{
						PopandClear( OVERWRITE );
						Select( prev_sel );
						return;
					}
					else
					{
						cur = prev;
						fix_vertex = cur;
						Cursor( cur );
					}
				}
				else
				{
					flag = FALSE;
					cur = Cursor( prev2 );
					fix_vertex = cur;
				}
			}
			else if( key == KEY_ROLLUP & flag == FALSE )
			{
				if( k < (j-1) )
					k++;
				else
					k = 0;
				EdgeGetVertex( edge, k, point );
				if( point[0] == prev )
					cur = point[1];
				else
					cur = point[0];
				Cursor( cur );
			}
			else if( key == KEY_ROLLDOWN & flag == FALSE )
			{
				if( k > 0 )
					k--;
				else
					k = j-1;
				EdgeGetVertex( edge, k, point );
				if( point[0] == prev )
					cur = point[1];
				else
					cur = point[0];
				Cursor( cur );
			}
			else if ( key == 'p' )
			{
				cur = PolyPlane( cur, MouseWindow(),
						plane[0], plane[1], plane[2] );
				Cursor( cur );
			}
			else
				temp = KeyProcess( key );
			if( ((key!=0 ) & (key != INPUT_KEY)) | ( pick != Cursor()) )
			{
				if( flag == FALSE )
					DrawLine( pick, prev );
				else
				{
					DrawLine( pick, prev );
					DrawLine( pick, prev2 );
				}
				draw_flag = ON;
			}
			else
				draw_flag = OFF;
			pick = Cursor();
			input_flag = OFF;
		}
		if( flag == TRUE )
			break;
		else
		{
			flag = TRUE;
			prev2 = cur;
			DrawLine( pick, prev );
			cur = (prev+prev2)*scale(UNIT_MATRIX, 0.5,0.5,0.5 );
			Cursor( cur );
			fix_vertex = cur;
			draw_flag = ON;
			pick = cur;
		}
	}
	Clear( OVERWRITE );
	Select( work_sel );
	cur_pos = Position( cur );
	while( PolyLoad())
	{
		vers = PolyVertexs();
		ty = PolyType();
		for( i = 0; i< vers; i++ )
		{
			temp = PolyGetVertex( i );
			if( temp == prev | temp == prev2 )
			{
				if( i == 0 )
				{
					temp2 = PolyGetVertex( 1 );
					if( temp2 == prev | temp2 == prev2 )
					{
						flag = ON;
						i++;
						break;
					}
					temp2 = PolyGetVertex( vers -1 );
					if( temp2 == prev | temp2 == prev2 )
					{
						flag = OFF;
						break;
					}
				}
				else
				{
					temp2 = PolyGetVertex( i+1 );
					if( temp2 == prev | temp2 == prev2 )
					{
						i++;
						flag = ON;
						break;
					}
				}
			}
		}
		if( ty == POLY_SHADE )
		{
			temp_vec = Vector( temp );
			temp2_vec = Vector( temp2 );
			cur = Vertex( cur_pos, unit(temp_vec+temp2_vec ) );
		}
		else if( ty == POLY_UV )
		{
			Mapping( temp, temp_map );
			Mapping( temp2, temp2_map );
			temp_map[0] = (temp_map[0]+temp2_map[0])/2;
			temp_map[1] = (temp_map[1]+temp2_map[1])/2;
			cur = Vertex(	cur_pos, 1, 1, 1,
					temp_map[0], temp_map[1] );
		}
		else if( ty == POLY_UVSHADE )
		{
			temp_vec = Vector( temp );
			temp2_vec = Vector( temp2 );
			Mapping( temp, temp_map );
			Mapping( temp2, temp2_map );
			temp_map[0] = (temp_map[0]+temp2_map[0])/2;
			temp_map[1] = (temp_map[1]+temp2_map[1])/2;
			cur = Vertex(	cur_pos, unit(temp_vec+temp2_vec ),
					temp_map[0], temp_map[1] );
		}
		if( flag == ON )
			PolyInsVertex( cur, i );
		else
			PolySetVertex( cur, vers );
		PolyVertexs( vers+1 );
		PolySave();
	}
	Select( prev_sel );
	Update( CLEAR );
	UpdateObject();
	pers_rotation_flag = FALSE;
	PopMenu();
	StatusBar(statustext);
	Status_title = Status_org;
	DrawStatus();
}

//
//	点削除
//
function private _DelVertex()
{
	var prev_sel;
	var i, vers, flag;

	cur = Cursor();
	if (cur != PolyVertex( cur ))
	{
		Warning();
		if( MESSAGE == ON )
			Message( error_msg1 );
		return ;
	}

	prev_sel = Select();
	if(( ShiftStat() & 1 ) == 1 )
	{
		if( SelectPolygons() == 0 )
			SelectAll( TRUE );
	}
	else
		SelectAll( TRUE );
	SelectArea( TRUE, SELECT_AND | SELECT_SUB, cur, cur );
	if( SelectPolygons() == 0 )
	{
		Warning();
		Select( prev_sel );
		return;
	}

	flag = FALSE;
	while( PolyLoad())
	{
		vers = PolyVertexs();
		if( vers > 3 )
		{
			for( i = 0;i<vers;i++ )
			{
				if( PolyGetVertex( i ) == cur )
					break;
			}
			if( i < vers )
			{
				PolyDelVertex( i );
				PolySave();
				flag = TRUE;
			}
		}
	}
	Select( prev_sel );
	if( flag == FALSE )
		Warning();
	else
	{
		Update( CLEAR );
		pers_rotation_flag = FALSE;
		UpdateObject();
	}
}

//
//	選択範囲を平行移動
//
function _MoveSelect()
{
	var	org, org_pos[2], point[2], temp_point[2];
	var	i, j, k, vers;
	var	mat, move_vec[3];
	var	key;
	var	temp, temp2, temp3;
	var	pick, draw_flag = ON, mode = OFF;
	var	edge, edge1, edge2, edge_temp;
	var	prev_sel, sel1, sel2;
	var	change_ver[MAXVERTEX], change;
	var	change_flag = OFF;

	if ( SelectPolygons() == 0 )
	{
		Warning();
		if( MESSAGE == ON )
			Message( error_msg3 );
		return ;
	}

	PushMenu();
	Status_org = Status_title;
	MenuPosition( Menu( " 動作設定(&S)",
			"移動中止	ESC",	MenuQuit
		), Menu_Title );
	ClearStatus();
	Status_title[0] = "【選択面を平行移動中】";
	DrawStatus();
	quit_flag = FALSE;

	prev_sel = Select();
	SelectBox( org_pos );

	sel1 = Select();
	edge1 = EdgeSelect();
	sel2 = SelectAdjoint( sel1 );
	sel2 = sel2 & ( !sel1 );
	Select( sel2 );
	edge2 = EdgeSelect();
	edge2 = edge2 - edge1;
	edge  = Edge();
	for( i = 0; i< Edges(edge2 );i++ )
	{
		EdgeGetVertex( edge2, i, point );
		Select( prev_sel );
		SelectArea( TRUE, SELECT_AND | SELECT_SUB, point[0], point[0] );
		if( SelectPolygons() != 0 )
		{
			edge_temp = Edge( point[0], point[1] );
			EdgeGetVertex( edge_temp, 0, temp_point );
			if( temp_point[0] == point[0] )
				edge = edge + edge_temp;
			else
			{
				edge = edge + edge_temp;
				edge = edge + edge_temp;
			}
		}
		else
		{
			Select( prev_sel );
			SelectArea( TRUE, SELECT_AND | SELECT_SUB, point[1], point[1] );
			if( SelectPolygons() != 0 )
			{
				edge_temp = Edge( point[0], point[1] );
				EdgeGetVertex( edge_temp, 0, temp_point );
				if( temp_point[0] == point[1] )
					edge = edge + edge_temp;
				else
				{
					edge = edge + edge_temp;
					edge = edge + edge_temp;
				}
			}
		}
	}
	j = Edges( edge );

	org = Cursor();
	cur = org;
	pick = cur;
	fix_vertex = cur;
	Select( prev_sel );
	edge_temp = EdgeSelect();
	k = Edges( edge_temp );
	input_flag = OFF;
	while( TRUE )
	{
		if( draw_flag == ON )
		{
			mat = move( UNIT_MATRIX, (Position( cur )- Position( org )));
			DrawLine( org, cur );
			if( mode == OFF )
				DrawBox( org_pos[0], org_pos[1], mat );
			else
			{
				for(i = 0; i< k; i++ )
				{
					EdgeGetVertex( edge_temp, i, temp_point );
					DrawLine( temp_point[0]*mat, temp_point[1]*mat );
				}
				for( i = 0; i< j; i++ )
				{
					EdgeGetVertex( edge, i, point );
					if( EdgeGetCount( edge, i ) == 1 )
						DrawLine( point[0]*mat, point[1] );
					else
						DrawLine( point[0], point[1]*mat );
				}
			}
		}
		key = WaitEvent();
		if( key )
			input_flag = ON;
		if( (( ShiftStat() & 1 ) == 1))
		{
			cur = Cursor();
			TrimCursor(fix_vertex, MouseWindow());
			Cursor( cur );
		}
		else
			cur = Cursor();
		key = KeyCode();
		if( input_flag | key == INPUT_KEY )
		{
			if( cur == org )
			{
				Warning();
				if( MESSAGE == ON )
					Message( error_msg5 );
			}
			else
				break;
		}
		else if(( key == ESC ) | ( key == BS ) | ( quit_flag == TRUE ))
		{
			PopandClear( OVERWRITE );
			Select( prev_sel );
			return;
		}
		else if( key =='c' )
			change_flag = ON;
		else
			temp = KeyProcess( key );
		if( ((key!=0 ) & (key != INPUT_KEY)) | ( pick != Cursor()) )
		{
			draw_flag = ON;
			mat = move( UNIT_MATRIX, (Position( pick ) - Position( org )));
			DrawLine( pick, org );
			if( mode == OFF )
				DrawBox( org_pos[0], org_pos[1], mat );
			else
				Clear( OVERWRITE );
		}
		else
			draw_flag = OFF;
		if( change_flag == ON )
			mode = !mode;
		change_flag = OFF;
		pick = Cursor();
		input_flag = OFF;
	}
	Clear( OVERWRITE );
	mat = move( UNIT_MATRIX, (Position( cur ) - Position( org )));
	Select(sel2 );
	k = SelectPolygons();
	for( i = 0; i< k; i++ )
	{
		PolyLoad( sel2, i );
		vers = PolyVertexs();
		change = 0;
		for( j = 0; j< vers; j++ )
		{
			temp = PolyGetVertex( j );
			Select( prev_sel );
			SelectArea( TRUE, SELECT_AND | SELECT_SUB, temp, temp );
			if( SelectPolygons() != 0 )
			{
				change_ver[change] = j;
				change++;
			}
		}
		PolyLoad( sel2, i );
		for( j = 0; j< change; j++ )
		{
			temp = PolyGetVertex( change_ver[j] );
			PolySetVertex( temp*mat, change_ver[j] );
		}
		PolySave();
	}
	Select( prev_sel );
	PolyMove( mat );
	Update( CLEAR );
	UpdateObject();
	pers_rotation_flag = FALSE;
	PopMenu();
	Status_title = Status_org;
	DrawStatus();
}

function _RotateSelect()
	_Rotate( ON );

function _ScaleSelect()
	_Scale( ON );

//
//	点移動
//
function MoveVertex()
{
	ClearStatus();
	Status_title[0] = "【ﾓｰﾄﾞ:点移動】";
	DrawStatus();
	InputEvent( _MoveVertex );
	KeyEvent( _MoveVertex, INPUT_KEY );
}

//
//	点追加
//
function AddVertex()
{
	ClearStatus();
	Status_title[0] = "【ﾓｰﾄﾞ:点追加】";
	DrawStatus();
	InputEvent( _AddVertex );
	KeyEvent( _AddVertex, INPUT_KEY );
}

//
//	点削除
//
function DelVertex()
{
	ClearStatus();
	Status_title[0] = "【ﾓｰﾄﾞ:点削除】";
	DrawStatus();
	InputEvent( _DelVertex );
	KeyEvent( _DelVertex, INPUT_KEY );
}

function MoveEdge()
{
	ClearStatus();
	Status_title[0] = "【ﾓｰﾄﾞ:辺を平行移動】";
	DrawStatus();
	InputEvent( _MoveEdge );
	KeyEvent( _MoveEdge, INPUT_KEY );
}

function RotateEdge()
{
	ClearStatus();
	Status_title[0]  = "【ﾓｰﾄﾞ:辺を回転】";
	DrawStatus();
	InputEvent( _RotateEdge );
	KeyEvent( _RotateEdge, INPUT_KEY );
}

function ScaleEdge()
{
	ClearStatus();
	Status_title[0] = "【ﾓｰﾄﾞ:辺を拡大縮小】";
	DrawStatus();
	InputEvent( _ScaleEdge );
	KeyEvent( _ScaleEdge, INPUT_KEY );
}

function MoveSelect()
{
	ClearStatus();
	Status_title[0] = "【ﾓｰﾄﾞ:選択面を移動】";
	DrawStatus();
	InputEvent( _MoveSelect );
	KeyEvent( _MoveSelect, INPUT_KEY );
}

function RotateSelect()
{
	ClearStatus();
	Status_title[0] = "【ﾓｰﾄﾞ:選択面を回転】";
	DrawStatus();
	InputEvent( _RotateSelect );
	KeyEvent( _RotateSelect, INPUT_KEY );
}

function ScaleSelect()
{
	ClearStatus();
	Status_title[0] = "【ﾓｰﾄﾞ:選択面を拡大縮小】";
	DrawStatus();
	InputEvent( _ScaleSelect );
	KeyEvent( _ScaleSelect, INPUT_KEY );
}

MenuPosition(
	Menu( " 変形(&T)",
		"点移動(&M)	1",	MoveVertex,PolyCheck,
		"点追加(&A)	2",	AddVertex,PolyFlagCheck,
		"点削除(&D)	3",	DelVertex,PolyFlagCheck,
		"----------------",		SEPARATE_MENU,
		"辺を平行移動(&E)	4",	MoveEdge,PolyFlagCheck,
		"辺を回転(&R)	5",	RotateEdge,PolyFlagCheck,
		"辺を拡大縮小(&S)	6",	ScaleEdge,PolyFlagCheck,
		"----------------",		SEPARATE_MENU,
		"選択面を平行移動(&P)	7",	MoveSelect,SelectCheck,
		"選択面を回転(&R)	8",	RotateSelect,SelectCheck,
		"選択面を拡大縮小(&S)	9",	ScaleSelect,SelectCheck
	), Menu_trans
);
