#include "stdafx.h"
#include "eb_api.h"		//	CAXA EB API 函数
#include "resource.h"

void dymGenTwoPtLine1(int& step,int& flag);		//	两点线方法1
void dymGenTwoPtLine2(int& step,int& flag);		//	两点线方法2

int	usrAppendDraw(int& step,int& flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())

	static int	choice=0;	//	注意这里一定要用静态(static)来声明用于纪录选择结果的变量!!!

    if(step==0)			//	第一步
	{
		ebClearMenu();	//	清理立即菜单区
		ebGetMenuChoiceBrk("两点线(方法1)@两点线(方法2)",&choice);	//弹出立即菜单项
		ebRegisterPopMenu();	//	登记工具点菜单
    }

    //	根据选择要绘制线的类型来执行相应的函数
    switch(choice) 
	{
		case 0:
			dymGenTwoPtLine1(step,flag);
			break;
		case 1:
			dymGenTwoPtLine2(step,flag);
			break;
		default:
			break;
    }

    return RT_NORMAL;
}

/*
	用第一种方法绘制两点线，这种方法是建立临时直线节点，通过绘制
	结点的办法来实现拖动效果，使用这种方法具有一定的通用性，可推
	广到绘制块、箭头、文字等复杂图形，但要特别注意的一点是，为了
	避免内存泄漏，当绘制完成或取消操作时应该及时使用ebFreeNode函
	数释放掉临时结点，这点非常重要!!!
*/
void dymGenTwoPtLine1(int &step,int &flag)
{
	static EB_POINT p1,p2;		//	注意:	这些在消息循环过程中要发生
    static int continues=0;		//			变化的量应采用静态声明
    static int maner=0;
    static int style=0;
    static double len = 100.0;
    int    ret = 0;
    int    ret1 = 0,ret2 = 0;

    static EB_NODE line=NULL;	//	临时直线,该直线用于中间过程的操作
	if(line==NULL)
		line=ebBuildLine(p1,p2);	//	如果临时直线还没有创建则先创建一条直线
	else
		ebSetLineData(line,p1,p2);	//	如果临时直线已经创建则根据两端点修改该直线直线

	//	以下的代码是为了实现绘制时的拖动效果,
    if(flag == ERASE_TRACE) //	如果当前绘图标志为擦除时
	{
		ebDrawXOR(TRUE);	//	打开异或绘图方式
		ebDrawNode(line);	//	绘制一遍直线
		ebFirstFlag=TRUE;	//	置首次绘制标志为真

		ebDrawXOR(FALSE);	//	关闭异或绘图方式
		return;
    }
    if(flag == UPDATE_TRACE) //	如果当前绘图标志为更新时
	{
		ebDrawXOR(TRUE);
		if(ebFirstFlag==TRUE)	//	如果这条直线从未画过,则将首次绘制标志置为假
			ebFirstFlag = FALSE;
		else					//	如果这条直线已经画过,则将再次绘制一遍这条直线,在异或方式下即擦除该直线
			ebDrawNode(line);

		ebGetPoint(&p2);	//	得到直线的第二点坐标
		ebSetLineData(line,p1,p2);	//	修改直线的两端点坐标

		ebDrawNode(line);	//	将修改后的直线重画一遍
		ebDrawXOR(FALSE);

		return;
	}

	switch(step) 
	{
	case 0:	//	第一步创建立即菜单,并提示输入直线的第一点
	    ebGetMenuChoice("连续@单个",&continues);
	    ebGetMenuChoice("非正交@正交",&maner);
	    ebGetMenuChoiceCondition("点方式@长度方式",&style,&maner,1);
	    ebGetMenuRealCondition("长度:",&len,0.0001,100000,&style,1);
		ebPrompt("第一点:");
	    break;
	case 1:	//	当用鼠标拾取点或用键盘输入点坐标后,提示输入第二点
	    ret1 = ebGetPoint(&p1);	//	得到第一点坐标
	    if(ret1==RT_FINISH||ret1==RT_USERBRK)		//	如果点鼠标右键或按键盘的ESC键,则结束绘图
		{
			ebFreeNode(line);	//	释放临时直线结点所占用内存
			line=NULL;
			ebEndCommand();		//	结束命令
			ebClearMenu();		//	清除菜单
			return;
	    }
		flag = UPDATE_TRACE;	//	设置绘图方式为更新方式
		ebSetLineData(line,p1,p2);
		if(style==0)			//	如果绘制普通两点线则提示输入第二点
			ebPrompt("第二点:");
		else if(style=1)		//	如果以正交方式绘制,则提示输入直线长度
			ebPrompt("输入长度:");
	    break;
	case 2:	//	第三步得到第二点坐标并绘制这条直线
	    ret2 = ebGetPoint(&p2);	//	取第二点坐标
	    if(ret2==RT_FINISH||ret2==RT_USERBRK)
		{
			ebFreeNode(line);	//	释放临时直线结点所占用内存
			line=NULL;
			ebEndCommand();
			ebClearMenu();
			return;
	    }
		if(maner==1) 
		{	//	正交线,仅作简化处理
			p2.x=p1.x+len;
			p2.y=p1.y;
		}

		ebInitUndo();	//	初始化UNDO/REDO缓冲区,这样可以是此后插入到
						//	系统图形数据库中的结点元素可执行UNDO/REDO操作
		EB_NODE m_line=ebBuildLine(p1,p2);	//	以p1和p2点创建一条新的直线结点
		ebInsNodeToSys(m_line);		//	将该直线插入到系统图形数据库		

	    if(continues==0)	//	如果要求绘制连续直线
		{	  //连续
			step = 1;		//	设定下一次消息循环从第二步开始
			p1=p2;
			flag = UPDATE_TRACE;
			ebPrompt("第二点:");
	    }
	    else
		{
			step = 0;
			ebPrompt("第一点:");			
	    }
	    break;
    }
}

/*
	用第二种方法绘制两点线，这种方法是利用直线的两个点坐标（静态值）
	和直接绘制直线的函数ebDrawLine绘制直线办法来实现拖动效果，而不必
	建立临时直线节点，因此不会涉及到内存泄漏，比较安全使用这种方法只
	适用于绘制点、直线、圆和圆弧几种简单的类型，通用性不如第一种方法
	但是使用起来比第一种方法简单，在绘制简单图形以及可以用简单类型组
	合的图形时应尽量使用这种方法。
*/
void dymGenTwoPtLine2(int &step,int &flag)
{

	static EB_POINT p1,p2;		//	注意:	这些在消息循环过程中要发生
    static int continues=0;		//			变化的量应采用静态声明
    static int maner=0;
    static int style=0;
    static double len = 100.0;
    int    ret = 0;
    int    ret1 = 0,ret2 = 0;

	//	以下的代码是为了实现绘制时的拖动效果,
    if(flag == ERASE_TRACE) //	如果当前绘图标志为擦除时
	{
		ebDrawXOR(TRUE);	//	打开异或绘图方式
		ebDrawLine(p1,p2,DRAGING);	//	利用直接绘制直线函数绘制一遍直线
		ebFirstFlag=TRUE;	//	置首次绘制标志为真
		ebDrawXOR(FALSE);	//	关闭异或绘图方式
		return;
    }
    if(flag == UPDATE_TRACE) //	如果当前绘图标志为更新时
	{
		ebDrawXOR(TRUE);
		if(ebFirstFlag==TRUE)	//	如果这条直线从未画过,则将首次绘制标志置为假
			ebFirstFlag = FALSE;
		else					//	如果这条直线已经画过,则将再次绘制一遍这条直线,在异或方式下即擦除该直线
			ebDrawLine(p1,p2,DRAGING);	//	利用直接绘制直线函数绘制一遍直线

		ebGetPoint(&p2);	//	得到直线的第二点坐标
		ebDrawLine(p1,p2,DRAGING);	//	利用直接绘制直线函数绘制一遍直线
		ebDrawXOR(FALSE);

		return;
	}

	switch(step) 
	{
	case 0:	//	第一步创建立即菜单,并提示输入直线的第一点
	    ebGetMenuChoice("连续@单个",&continues);
	    ebGetMenuChoice("非正交@正交",&maner);
	    ebGetMenuChoiceCondition("点方式@长度方式",&style,&maner,1);
	    ebGetMenuRealCondition("长度:",&len,0.0001,100000,&style,1);
		ebPrompt("第一点:");
	    break;
	case 1:	//	当用鼠标拾取点或用键盘输入点坐标后,提示输入第二点
	    ret1 = ebGetPoint(&p1);	//	得到第一点坐标
	    if(ret1==RT_FINISH||ret1==RT_USERBRK)		//	如果点鼠标右键或按键盘的ESC键,则结束绘图
		{
			ebEndCommand();		//	结束命令
			ebClearMenu();		//	清除菜单
			return;
	    }
		flag = UPDATE_TRACE;	//	设置绘图方式为更新方式
		if(style==0)			//	如果绘制普通两点线则提示输入第二点
			ebPrompt("第二点:");
		else if(style=1)		//	如果以正交方式绘制,则提示输入直线长度
			ebPrompt("输入长度:");
	    break;
	case 2:	//	第三步得到第二点坐标并绘制这条直线
	    ret2 = ebGetPoint(&p2);	//	取第二点坐标
	    if(ret2==RT_FINISH||ret2==RT_USERBRK)
		{
			ebEndCommand();
			ebClearMenu();
			return;
	    }
		if(maner==1) 
		{	//	正交线,仅作简化处理
			p2.x=p1.x+len;
			p2.y=p1.y;
		}

		ebInitUndo();	//	初始化UNDO/REDO缓冲区,这样可以是此后插入到
						//	系统图形数据库中的结点元素可执行UNDO/REDO操作
		EB_NODE m_line=ebBuildLine(p1,p2);	//	以p1和p2点创建一条新的直线结点
		ebInsNodeToSys(m_line);		//	将该直线插入到系统图形数据库		

	    if(continues==0)	//	如果要求绘制连续直线
		{	  //连续
			step = 1;		//	设定下一次消息循环从第二步开始
			p1=p2;
			flag = UPDATE_TRACE;
			ebPrompt("第二点:");
	    }
	    else
		{
			step = 0;
			ebPrompt("第一点:");			
	    }
	    break;
    }
}

//	以下函数的主要功能为拾取一条直线并修改该直线的终点
int usrAppendModify(int &step,int &flag)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())

	EB_POINT p,p1,p2;
	static EB_NODE line;
	switch(step)
	{
	case 0:
		ebPrompt("请拾取一条直线:");
		break;
	case 1:
		ebGetPoint(&p);
		line=ebGetNode(p,LINE);	//	拾取一条直线
		if(line==NULL)	//	如果拾取的不是一条直线则重新拾取
		{
			step=0;
			break;
		}
		ebPrompt("请拾取目标点:");
		break;
	case 2:
		ebGetPoint(&p);
		ebGetLineData(line,&p1,&p2);	//	先得到原来直线的端点坐标
		ebSetLineData(line,p1,p);		//	修改这条直线的端点坐标
		ebDrawNode(line,NORMAL);		//	重画该直线	
		ebRedraw();	
		ebEndCommand();					//	结束命令
		ebClearMenu();					//	清除菜单区
		break;
	}
	return 1;
}

