// RulesBackgroundStatic.cpp : implementation file
//

#include "stdafx.h"
#include "RulesBackgroundStatic.h"
#include "DlgRuleSet.h"
#include "DlgIntelligentLog.h"
#include "DlgWizardSecond.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define WM_NETCLIENT     WM_USER + 1

#define RE_LINK_TIMER     1

#define RELINK_INTERVAL  5000
#define REGION_FINISH_FLAG 35

void WINAPI DrawCallBack(HDC hDC,void *context)
{
    CMyRulesStatic* pWnd = (CMyRulesStatic*)context;
	if (pWnd->IsWindowVisible())
    {
		pWnd->DrawRules(hDC);
    }
}
/////////////////////////////////////////////////////////////////////////////
// CMyRulesStatic
extern CDlgSmartBasicSet*   g_dlgSmartBaseSet;

CMyRulesStatic::CMyRulesStatic():m_rule_shield_msk(-1)
{
    m_szDevname  = "video server";
    m_szUrl      = "192.168.1.192";
    m_ch         = 0;
    m_port       = 3000;
    m_szUsername = "888888";
    m_szPassword = "888888";

    m_hChan      = -1;
    m_bLinkOK    = FALSE;

    m_point.x = 0;
    m_point.y = 0;

	m_polylinefinish = FALSE;
    m_bEnableEdit    = FALSE;

    m_pen_normal_line.CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
    m_pen_object_area.CreatePen(PS_SOLID, 2, RGB(0, 0, 255));

    m_brush_rule_region.CreateHatchBrush(HS_BDIAGONAL, RGB(0, 0, 255));
    m_brush_msk_region.CreateHatchBrush(HS_BDIAGONAL, RGB(0, 255, 0));

    m_hCursorArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
    m_hCursorMove  = AfxGetApp()->LoadStandardCursor(IDC_SIZEALL);
    m_hCursorCross = AfxGetApp()->LoadCursor(IDC_CURSOR_CROSS);
    m_hCursorPencil= AfxGetApp()->LoadCursor(IDC_CURSOR_PENCIL);
    m_hCursorErase = AfxGetApp()->LoadCursor(IDC_CURSOR_ERASE);
    m_hCursorFill  = AfxGetApp()->LoadCursor(IDC_CURSOR_FILL);

    m_hBmpTargent  = (HBITMAP)LoadImage(AfxGetInstanceHandle(),
                                        MAKEINTRESOURCE(IDB_BITMAP_TARGENT),
                                        IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE);
  
    m_pSelectRule = NULL;
    InitValue();
}

CMyRulesStatic::~CMyRulesStatic()
{
    if( m_hBmpTargent )
		DeleteObject( m_hBmpTargent );

    m_pen_normal_line.DeleteObject();
    m_brush_rule_region.DeleteObject();
    m_brush_msk_region.DeleteObject();
	CleanRules();
	if (m_pSelectRule)
	{
		delete m_pSelectRule;
		m_pSelectRule = NULL;
	}
}


BEGIN_MESSAGE_MAP(CMyRulesStatic, CStatic)
	//{{AFX_MSG_MAP(CMyRulesStatic)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_RBUTTONDOWN()
    ON_WM_SETCURSOR()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
    ON_MESSAGE(WM_NETCLIENT,OnNetClientMsg)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyRulesStatic message handlers

void CMyRulesStatic::SetCameraLinkParam(LPCTSTR pDevname,LPCTSTR pUrl,UINT ch,UINT port,LPCTSTR pUsername,LPCTSTR pPsw)
{
    m_szDevname  = pDevname;
    m_szUrl      = pUrl;
    m_ch         = ch;
    m_port       = port;
    m_szUsername = pUsername;
    m_szPassword = pPsw;
}

BOOL CMyRulesStatic::Play()
{
    BOOL    iRet = FALSE;

    if( m_hChan == -1 && !m_bLinkOK )
    {
        iRet = ConnectChannel();
    }
    else if( m_bLinkOK )
    {
        iRet = Replay();
    }

    if( iRet )
        m_bPause = FALSE;

    return iRet;
}

BOOL CMyRulesStatic::Pause()
{
    if( m_hChan != -1 && m_bLinkOK )
    {
        if (VSNET_ClientMediaData(m_hChan,FALSE))
        {
            m_bPause = TRUE;
        }
    }

    return FALSE;
}

void CMyRulesStatic::Stop()
{
    if( m_hChan != -1 )
    {
        VSNET_ClientStop( m_hChan );
        m_hChan = -1;
    }

    m_bLinkOK = FALSE;
}

void CMyRulesStatic::OnNetClientMsg(WPARAM wParam,LPARAM lParam)
{
    if( wParam == LAUMSG_LINKMSG )
    {
        if( lParam == 0 )
        {        
            TRACE("Link %s url:%s ch:%d OK\n",m_szDevname,m_szUrl,m_ch);
			VSNET_ClientDrawCallBack(m_hChan, DrawCallBack, this);
			KillTimer(RE_LINK_TIMER);
            m_bLinkOK = TRUE;
        }
        else
        {
            TRACE("Link %s url:%s ch:%d Failed:%d\n",m_szDevname,m_szUrl,m_ch,lParam);
            Stop();
            SetTimer(RE_LINK_TIMER, RELINK_INTERVAL, NULL);
        }
    }
    if (wParam >= LAUMSG_VAALARM_SINGLELINE && wParam <= LAUMSG_VAALARM_REGIONWANDER)
    {
        if (lParam & (1<<m_ch))
        {
            //((CDlgIntelligentBasicSet*)GetParent())->OnVAAlarm(wParam);
			//g_dlgSmartSetLog->PostMessage(WM_UPALARMLOG,wParam);
        }
    }
}

BOOL CMyRulesStatic::ConnectChannel()
{
    ASSERT( m_hChan == -1 && !m_bLinkOK );

    CHANNEL_CLIENTINFO  pChaninfo;
    memset(&pChaninfo,0,sizeof(CHANNEL_CLIENTINFO));

    pChaninfo.m_sername         = (char*)LPCTSTR(m_szDevname);
	pChaninfo.m_username        = (char*)LPCTSTR(m_szUsername);
	pChaninfo.m_password        = (char*)LPCTSTR(m_szPassword);
	pChaninfo.m_tranType        = 3;
	pChaninfo.m_playstart       = TRUE;
	pChaninfo.m_ch              = m_ch;
	pChaninfo.m_hVideohWnd      = m_hWnd;
	pChaninfo.m_hChMsgWnd       = m_hWnd;
	pChaninfo.m_nChmsgid        = WM_NETCLIENT;
	pChaninfo.m_buffnum         = 50;
	pChaninfo.m_useoverlay      = FALSE;
    pChaninfo.nColorKey         = RGB(255,0,255);
	strcpy(pChaninfo.url,m_szUrl);
	pChaninfo.m_messagecallback = NULL;
	pChaninfo.context           = NULL;

    m_hChan = VSNET_ClientStart((char*)(LPCTSTR)m_szUrl, &pChaninfo,m_port);
    return m_hChan != -1;
}

BOOL CMyRulesStatic::Replay()
{
    if( m_hChan != -1 && m_bLinkOK )
    {
        return VSNET_ClientMediaData(m_hChan,TRUE);
    }

    return FALSE;
}

BOOL CMyRulesStatic::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{	
	return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
}
void CMyRulesStatic::OnLButtonDblClk(UINT nFlags,CPoint point)
{
	OnKeyControl(VK_ESCAPE, FALSE);

	CStatic::OnLButtonDblClk(nFlags,point);
}
void CMyRulesStatic::PreSubclassWindow() 
{
    GetClientRect( &m_rect );
	CStatic::PreSubclassWindow();
}

void CMyRulesStatic::OnPaint() 
{
	CPaintDC dc(this);

    if (m_hChan != -1 && m_bLinkOK)
    {
        VSNET_ClientRefrenshWnd(m_hChan);
    }
    else
    {
        CRect   rc;
        GetClientRect(&rc);
        dc.FillSolidRect(&rc,RGB(0,0,0));
    }

    //DrawRules(dc.m_hDC);
}

void CMyRulesStatic::OnTimer(UINT nIDEvent)
{
    if (nIDEvent == RE_LINK_TIMER)
    {
		Play();
    }
    CStatic::OnTimer(nIDEvent);
}
void CMyRulesStatic::OnLButtonDown(UINT nFlags, CPoint point) 
{
    CRegionRule   *pRegionRule;
    
    m_point = point;
    
    pRegionRule = m_bEditShieldMsk?&m_rule_shield_msk:(CRegionRule*)m_pSelectRule;

    switch (m_editActionType)
    {
    case EDITRULE_ACTION_NONE:
        if (m_pSelectRule && m_pSelectRule->m_ruleType == RULE_TYPE_SINGLELINE && m_bEnableEdit)
        {
            if (((CSingleLineRule*)m_pSelectRule)->CheckHotPoint(point) )
            {
                m_editActionType = EDITRULE_ACTION_HOTPOINT;
				{
					CRect rc;
					GetWindowRect(&rc);
					ClipCursor(&rc);
				}
            }
        }
        break;
    case EDITRULE_ACTION_MOVE:
        m_editActionType = EDITRULE_ACTION_MOVEING;
        break;
    case EDITRULE_ACTION_PENCIL:
        m_editActionType = EDITRULE_ACTION_PENCILING;
        pRegionRule->AddRegion(CRect(point.x, point.y, point.x+m_lineWidth, point.y+m_lineWidth));
        RefreshWindow();
        break;
    case EDITRULE_ACTION_ERASE:
        m_editActionType = EDITRULE_ACTION_ERASEING;
        pRegionRule->DelRegion(CRect(point.x, point.y, point.x+m_lineWidth, point.y+m_lineWidth));
        RefreshWindow();
        break;
    case EDITRULE_ACTION_REGION_RECT:
		{
			CRect rc;
			GetWindowRect(&rc);
			ClipCursor(&rc);
		}
        m_region_tmp_rect.left   = point.x;
        m_region_tmp_rect.top    = point.y;
        m_region_tmp_rect.right  = point.x;
        m_region_tmp_rect.bottom = point.y;
        m_bRegionRectValid       = TRUE;
        m_editActionType         =  EDITRULE_ACTION_REGION_RECTING;
        break;
    case EDITRULE_ACTION_REGION_FILL:
        if( m_bRegionRectValid && m_region_tmp_rect.PtInRect(point) )
        {
            pRegionRule->AddRect(m_region_tmp_rect);
            m_bRegionRectValid = FALSE;
            m_region_tmp_rect.InflateRect(1,1);
            RefreshWindow(&m_region_tmp_rect);
        }
        else if( m_region_tmp_count > 1 && PtInPolygon(point) )
        {
            pRegionRule->AddPolygon(m_region_tmp_polygon_point, m_region_tmp_count);
            m_region_tmp_count = 0;
            RefreshWindow();
        }
        break;
    case EDITRULE_ACTION_REGION_POLYGON:
		{
			CRect rc;
			GetWindowRect(&rc);
			ClipCursor(&rc);
		}
		m_polylinefinish = FALSE;
        m_region_tmp_count = 0;
        AddRegionPolyPoint(point);
        AddRegionPolyPoint(point);
        m_editActionType = EDITRULE_ACTION_REGION_POLYGONING;
        break;
    case EDITRULE_ACTION_REGION_POLYGONOVER:
        m_region_tmp_polygon_point[m_region_tmp_count-1].x = m_region_tmp_polygon_point[0].x;
        m_region_tmp_polygon_point[m_region_tmp_count-1].y = m_region_tmp_polygon_point[0].y;
        m_editActionType = EDITRULE_ACTION_REGION_POLYGON;

        //不用画刷手动填充，自动填充
#if 1
			pRegionRule->AddPolygon(m_region_tmp_polygon_point, m_region_tmp_count);
			m_region_tmp_count = 0;
			RefreshWindow();
		    m_polylinefinish = FALSE;
#endif

        break;
    case EDITRULE_ACTION_OBJECT_MIN_AREA:
		{
			CRect rc;
			GetWindowRect(&rc);
			ClipCursor(&rc);
		}
        m_object_min_area = CRect(point, point);
        m_editActionType = EDITRULE_ACTION_OBJECT_MIN_AREAING;
        break;
    case EDITRULE_ACTION_OBJECT_MAX_AREA:
		{
			CRect rc;
			GetWindowRect(&rc);
			ClipCursor(&rc);
		}
        m_object_max_area = CRect(point, point);
        m_editActionType = EDITRULE_ACTION_OBJECT_MAX_AREAING;
        break;
    default:
        break;
    }

    SetFocus();
	CStatic::OnLButtonDown(nFlags, point);
}

void CMyRulesStatic::OnRButtonDown(UINT nFlags, CPoint point)
{
	OnKeyControl(VK_ESCAPE, FALSE);
		
	CStatic::OnRButtonDown(nFlags,point);
}

void CMyRulesStatic::OnMouseMove(UINT nFlags, CPoint point) 
{
    CRegionRule   *pRegionRule; 
    pRegionRule = m_bEditShieldMsk?&m_rule_shield_msk:(CRegionRule*)m_pSelectRule;

    switch (m_editActionType)
    {
    case EDITRULE_ACTION_MOVEING:
    case EDITRULE_ACTION_HOTPOINT:
        {
            int offset_x,offset_y;
        
            offset_x = point.x - m_point.x;
            offset_y = point.y - m_point.y;
        
            ((CSingleLineRule*)m_pSelectRule)->EditSingleLineRule(offset_x,offset_y,m_editActionType);
            m_point = point;
        }
        RefreshWindow();
        break;
    case EDITRULE_ACTION_PENCILING:
        {
            CRect rect(point.x, point.y, point.x+m_lineWidth, point.y+m_lineWidth);
            pRegionRule->AddRegion(&rect);
            RefreshWindow();
        }
        break;
    case EDITRULE_ACTION_ERASEING:
        {
            CRect rect(point.x, point.y, point.x+m_lineWidth, point.y+m_lineWidth);
            pRegionRule->DelRegion(&rect);
            RefreshWindow();
        }
        break;
    case EDITRULE_ACTION_REGION_RECTING:
        m_region_tmp_rect.right  = point.x;
        m_region_tmp_rect.bottom = point.y;
        RefreshWindow();
        break;
    case EDITRULE_ACTION_REGION_POLYGONING:
    case EDITRULE_ACTION_REGION_POLYGONOVER:
        m_region_tmp_polygon_point[m_region_tmp_count-1].x = point.x;
        m_region_tmp_polygon_point[m_region_tmp_count-1].y = point.y;
        if (m_region_tmp_count >= 3)
        {           
            int x_off,y_off;
            x_off = m_region_tmp_polygon_point[0].x - m_region_tmp_polygon_point[m_region_tmp_count-1].x;
            y_off = m_region_tmp_polygon_point[0].y - m_region_tmp_polygon_point[m_region_tmp_count-1].y;
            
            if (x_off >= -REGION_FINISH_FLAG && x_off <= REGION_FINISH_FLAG 
                && y_off >= -REGION_FINISH_FLAG && y_off <= REGION_FINISH_FLAG)
            {
                m_editActionType = EDITRULE_ACTION_REGION_POLYGONOVER;
            }
            else
            {
                m_editActionType = EDITRULE_ACTION_REGION_POLYGONING;
            }
        }
        RefreshWindow();
        break;
    case EDITRULE_ACTION_OBJECT_MIN_AREAING:
        m_object_min_area.right  = point.x;
        m_object_min_area.bottom = point.y;
        ((CDlgSmartBasicSet*)GetParent())->OnObjectMinAreaChange(m_object_min_area.Width()*m_object_min_area.Height());
        RefreshWindow();
        break;
    case EDITRULE_ACTION_OBJECT_MAX_AREAING:
        m_object_max_area.right  = point.x;
        m_object_max_area.bottom = point.y;
        ((CDlgSmartBasicSet*)GetParent())->OnObjectMaxAreaChange(m_object_max_area.Width()*m_object_max_area.Height());
        RefreshWindow();
        break;
    }
    SetFocus();
	CStatic::OnMouseMove(nFlags, point);
}

void CMyRulesStatic::OnLButtonUp(UINT nFlags, CPoint point) 
{
    switch (m_editActionType)
    {
    case EDITRULE_ACTION_MOVEING:
        m_editActionType = EDITRULE_ACTION_MOVE;
        break;
    case EDITRULE_ACTION_HOTPOINT:
        if (((CSingleLineRule*)m_pSelectRule)->m_bMultiSegment && !((CSingleLineRule*)m_pSelectRule)->m_bFinish)
        {
            AddNextMultiSegment((CSingleLineRule*)m_pSelectRule);
        }
        else
        {
			ClipCursor(NULL);
            m_editActionType = EDITRULE_ACTION_NONE;
        }
        break;
    case EDITRULE_ACTION_PENCIL:
        break;
    case EDITRULE_ACTION_PENCILING:
        m_editActionType = EDITRULE_ACTION_PENCIL;
        break;
    case EDITRULE_ACTION_ERASE:
        break;
    case EDITRULE_ACTION_ERASEING:
        m_editActionType = EDITRULE_ACTION_ERASE;
        break;
    case EDITRULE_ACTION_REGION_RECT:
        break;
    case EDITRULE_ACTION_REGION_RECTING:
		m_polylinefinish = TRUE;
        m_editActionType = EDITRULE_ACTION_REGION_RECT;
		ClipCursor(NULL);        
        //不用画刷手动填充，自动填充
		
#if 1
		CRegionRule   *pRegionRule;		  
        pRegionRule = m_bEditShieldMsk?&m_rule_shield_msk:(CRegionRule*)m_pSelectRule;
        pRegionRule->AddRect(m_region_tmp_rect);
		m_bRegionRectValid = FALSE;
		m_region_tmp_rect.InflateRect(1,1);
        RefreshWindow(&m_region_tmp_rect);
		m_polylinefinish = FALSE;
#endif
        break;
    case EDITRULE_ACTION_REGION_FILL:
        break;
    case EDITRULE_ACTION_REGION_POLYGON:
		ClipCursor(NULL);
		m_polylinefinish = TRUE;
        break;
    case EDITRULE_ACTION_REGION_POLYGONING:
        AddRegionPolyPoint(point);
        break;
    case EDITRULE_ACTION_OBJECT_MIN_AREAING:
		ClipCursor(NULL);
        m_object_min_area.right  = point.x;
        m_object_min_area.bottom = point.y;
        m_editActionType = EDITRULE_ACTION_OBJECT_MIN_AREA;
        break;
    case EDITRULE_ACTION_OBJECT_MAX_AREAING:
		ClipCursor(NULL);
        m_object_max_area.right  = point.x;
        m_object_max_area.bottom = point.y;
        m_editActionType = EDITRULE_ACTION_OBJECT_MAX_AREA;
        break;
    default:
        m_editActionType = EDITRULE_ACTION_NONE;
    }
//	((CDlgSmartBasicSet*)GetParent())->ChangeBtnStatus(NULL);

    SetFocus();
	CStatic::OnLButtonUp(nFlags, point);
}
void CMyRulesStatic::DrawArea(CPoint begin)//,UINT nFlags)
{
	ScreenToClient(&begin);
	OnLButtonDown(0,begin);
	begin.Offset(30,30);
	OnMouseMove(0,begin);
	ClientToScreen(&begin);
	SetCursorPos(begin.x,begin.y);
}
BOOL CMyRulesStatic::AddNewRule(int ruleType,char *ruleName)
{
    CMyRule*  pNewRule = NULL;

    if( ruleType == NEWRULE_TYPE_SINGLELINE )
    {
        //添加单线规则
        pNewRule = AddSingleLineRule(FALSE,NULL,ruleName);
    }
    else if( ruleType == NEWRULE_TYPE_MULTISEGMENT)
    {
        //添加折线规则
        pNewRule = AddSingleLineRule(TRUE,NULL,ruleName);
    }
    else if( ruleType >= NEWRULE_TYPE_REGION )
    {
        //添加区域规则
        pNewRule = AddRegionRule(ruleType - NEWRULE_TYPE_REGION,ruleName);
    }

    return pNewRule != NULL;
}

CMyRule* CMyRulesStatic::AddSingleLineRule(BOOL bMultiSegment, CSingleLineRule* pCopySrCMyRule,char *ruleName)
{
    CSingleLineRule*  pSingleRule = NULL;

    if( GetSingleLineRuleCount() >= SINGLELINE_RULE_MAXCOUNT )
    {
        CString     szInfo;
        szInfo.Format("新建规则失败:警戒线数目已到最大值!");
        ::AfxMessageBox(szInfo);
        return NULL;
    }
    else if (bMultiSegment && pCopySrCMyRule)
    {
        if (GetSingleLineRuleCount() + pCopySrCMyRule->GetLineCount() > SINGLELINE_RULE_MAXCOUNT)
        {
            CString     szInfo;
            szInfo.Format("复制规则失败:警戒线数目已到最大值!");
            ::AfxMessageBox(szInfo);
            return NULL;
        }
    }

    if (pCopySrCMyRule)
    {
        pSingleRule = new CSingleLineRule(pCopySrCMyRule);
        TRACE("New pSingleRule:0x%08x\n",pSingleRule);
    }
    else
    {
        pSingleRule = new CSingleLineRule();
		
    }
    if( pSingleRule == NULL ) return FALSE;
	if(ruleName != NULL)
		pSingleRule->m_ruleName = ruleName;

	pSingleRule->m_bMultiSegment = bMultiSegment;

	if(bMultiSegment)m_multilinecount++;

    m_rulesList.AddTail(pSingleRule);

    return pSingleRule;
}

CMyRule* CMyRulesStatic::AddDoubleLineRule(CDoubleLineRule* pCopySrCMyRule,char *ruleName)
{
    return NULL;
}

CMyRule* CMyRulesStatic::AddRegionRule(int regionDrc,char *ruleName)
{
    CRegionRule*  pRegionRule = NULL;

    if (GetRegionRuleCount(regionDrc) >= REGION_RULE_MAXCOUNT)
    {
        CString     szInfo;
        szInfo.Format("新建规则失败:警戒区域数目已到最大值!");
        ::AfxMessageBox(szInfo);
        return NULL;
    }
    
    pRegionRule = new CRegionRule(regionDrc);
    if (pRegionRule == NULL)
    {
        return FALSE;
    }
	if(ruleName != NULL)
		pRegionRule->m_ruleName = ruleName;

    m_rulesList.AddTail(pRegionRule);
    return pRegionRule;
}

void CMyRulesStatic::DrawRules(HDC hDC)
{
    CRect     rc;
    CDC*      pDC = CDC::FromHandle( hDC );

    if (m_pSelectRule)
    {
        switch( m_pSelectRule->m_ruleType )
        {
        case RULE_TYPE_SINGLELINE:
			try{
				if (((CSingleLineRule*)m_pSelectRule)->m_bInitDraw)
					((CSingleLineRule*)m_pSelectRule)->DrawRule(pDC, this);
			}
			catch (...) {
			}
            break;
        case RULE_TYPE_DOUBLELINE:
            ((CDoubleLineRule*)m_pSelectRule)->DrawRule(pDC, this);
            break;
        case RULE_TYPE_REGION:
            DrawRegionRule(pDC);
            break;
        default:
            break;
        }
    }

    DrawRegion(pDC, &m_rule_shield_msk.m_rgn,&m_brush_msk_region,RGB(0,0,255));
    
    if (m_bEditShieldMsk)
    {
        if (m_bRegionRectValid)
        {
            HBRUSH  hOldBrush;
            CPen    *pOldPen;
        
            pOldPen   = pDC->SelectObject(&m_pen_normal_line);
            hOldBrush = (HBRUSH)pDC->SelectObject(GetStockObject(NULL_BRUSH));
            pDC->Rectangle(m_region_tmp_rect);
            pDC->SelectObject(&pOldPen);
            pDC->SelectObject(hOldBrush);
        }

        if( m_region_tmp_count > 0 )
        {
            CPen    *pOldPen;

            pOldPen  = pDC->SelectObject(&m_pen_normal_line);
            pDC->MoveTo(m_region_tmp_polygon_point[0].x,m_region_tmp_polygon_point[0].y);
            for(int index=1; index<m_region_tmp_count; index++)
            {
                pDC->LineTo(m_region_tmp_polygon_point[index].x,m_region_tmp_polygon_point[index].y);
            }
            pDC->SelectObject(&pOldPen);
        }
    }

    if ( m_editActionType == EDITRULE_ACTION_OBJECT_MIN_AREA
      || m_editActionType == EDITRULE_ACTION_OBJECT_MIN_AREAING)
    {
        HBRUSH  hOldBrush;
        CPen    *pOldPen;
        
        pOldPen   = pDC->SelectObject(&m_pen_object_area);
        hOldBrush = (HBRUSH)pDC->SelectObject(GetStockObject(NULL_BRUSH));
        pDC->Rectangle(m_object_min_area);
        pDC->SelectObject(&pOldPen);
        pDC->SelectObject(hOldBrush);
    }

    if ( m_editActionType == EDITRULE_ACTION_OBJECT_MAX_AREA
      || m_editActionType == EDITRULE_ACTION_OBJECT_MAX_AREAING)
    {
        HBRUSH  hOldBrush;
        CPen    *pOldPen;
        
        pOldPen   = pDC->SelectObject(&m_pen_object_area);
        hOldBrush = (HBRUSH)pDC->SelectObject(GetStockObject(NULL_BRUSH));
        pDC->Rectangle(m_object_max_area);
        pDC->SelectObject(&pOldPen);
        pDC->SelectObject(hOldBrush);
    }
}

void CMyRulesStatic::CleanRules()
{
    CMyRule*  pRule;

	int count;
    while( (count = m_rulesList.GetCount()) > 0 )
    {
        pRule = (CMyRule*)m_rulesList.RemoveHead();

        if (pRule == m_pSelectRule)
        {
            m_pSelectRule = NULL;
        }
        delete pRule;
    }

    if (m_pSelectRule != NULL)
    {
        delete m_pSelectRule;
        m_pSelectRule = NULL;
    }
}

BOOL CMyRulesStatic::EnableRuleMove(BOOL bEnable)
{
    if( bEnable )
    {
        if( m_pSelectRule )
        {
            m_editActionType = EDITRULE_ACTION_MOVE;
            return TRUE;
        }

        return FALSE;
    }
    else
    {
        m_editActionType  = EDITRULE_ACTION_NONE;
        return TRUE;
    }
}

BOOL CMyRulesStatic::SetSingleLineRuleDrc(int direction)
{
    if( m_pSelectRule && m_pSelectRule->m_ruleType == RULE_TYPE_SINGLELINE )
    {
        ((CSingleLineRule*)m_pSelectRule)->SetDirection(direction);
        RefreshWindow();

        return TRUE;
    }
    return FALSE;
}

BOOL CMyRulesStatic::DeleteRuleByIndex(int index)
{
	
    POSITION    pos;
    if( m_rulesList.GetCount() <= index ) return FALSE;

    pos = m_rulesList.FindIndex(index);

    if (pos)
    {
        CMyRule*  pRule = (CMyRule*)m_rulesList.GetAt(pos);

        m_rulesList.RemoveAt(pos);
        if (pRule == m_pSelectRule)
        {
            m_pSelectRule = NULL;
            RefreshWindow();
        }
		if(pRule->m_ruleTypeName.Compare("多段绊线规则") == 0)
			m_multilinecount --;

        delete pRule;
        return TRUE;
    }

    return FALSE;
}

void CMyRulesStatic::OnKeyControl(int nVirtKey, BOOL bKeyDown)
{
    if( !bKeyDown )
    {
        if (nVirtKey == VK_ESCAPE || nVirtKey == VK_RETURN)
        {
            if (m_pSelectRule && m_pSelectRule->m_ruleType == RULE_TYPE_SINGLELINE
                && ((CSingleLineRule*)m_pSelectRule)->m_bInitDraw
                && ((CSingleLineRule*)m_pSelectRule)->m_bMultiSegment)
            {
                ((CSingleLineRule*)m_pSelectRule)->FinishDraw();
				ClipCursor(NULL);
                m_editActionType = EDITRULE_ACTION_NONE;
            }
        }
        else if (nVirtKey == VK_DELETE)
        {
            if (   m_pSelectRule && m_pSelectRule->m_ruleType == RULE_TYPE_SINGLELINE 
               && ((CSingleLineRule*)m_pSelectRule)->m_bInitDraw)
            {
                m_editActionType = EDITRULE_ACTION_NONE;
                ((CSingleLineRule*)m_pSelectRule)->Reset();
                RefreshWindow();
            }
            else if (m_pSelectRule && m_pSelectRule->m_ruleType == RULE_TYPE_REGION)
            {
                ((CRegionRule*)m_pSelectRule)->CleanAllRegion();
                RefreshWindow();
            }
        }
    }
}

BOOL CMyRulesStatic::AddNextMultiSegment(CSingleLineRule *pSingleRule)
{
    CSingleLineRule*  pNewSingleRule = NULL;
    CSingleLineRule*  pLastSingleRule = NULL;

    if( GetSingleLineRuleCount() > SINGLELINE_RULE_MAXCOUNT )
    {
        CString     szInfo;
        szInfo.Format("警戒线数目已到最大值!");
        ::AfxMessageBox(szInfo);
        return FALSE;
    }

    pNewSingleRule  = new CSingleLineRule();
    if( pNewSingleRule )
    {
        pNewSingleRule->m_bMultiSegment = TRUE;
        pLastSingleRule = pSingleRule->GetLastSegment();
        
        pNewSingleRule->m_Rule.m_sgline_drc   = pLastSingleRule->m_Rule.m_sgline_drc;
        pNewSingleRule->m_Rule.m_sgline_beg_x = pLastSingleRule->m_Rule.m_sgline_end_x;
        pNewSingleRule->m_Rule.m_sgline_beg_y = pLastSingleRule->m_Rule.m_sgline_end_y;
        pNewSingleRule->m_Rule.m_sgline_end_x = pNewSingleRule->m_Rule.m_sgline_beg_x;
        pNewSingleRule->m_Rule.m_sgline_end_y = pNewSingleRule->m_Rule.m_sgline_beg_y;

        pLastSingleRule->m_pNextLine = pNewSingleRule;

        pSingleRule->m_pHotPointLine = pNewSingleRule;
        pSingleRule->m_hotPoint      = SINGLELINE_HOTPOINT_END;
        m_editActionType             = EDITRULE_ACTION_HOTPOINT;      

        RefreshWindow();
        return TRUE;
    }
    return FALSE;
}

BOOL CMyRulesStatic::LoadRulesSettings()
{
    BOOL  iRet = FALSE;
    LONG  hParam;
	CString rpt;
	rpt = "";

	m_hMutexSet.Lock();
	try
	{
		hParam = VSNET_ClientMessageOpen((char*)(LPCTSTR)m_szDevname,  (char*)(LPCTSTR)m_szUrl, 
										 (char*)(LPCTSTR)m_szUsername, (char*)(LPCTSTR)m_szPassword, m_port);

		if (hParam)
		{
			iRet = VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_GETALARMLINERULES, m_ch, &(g_dlgSmartBaseSet->m_singleRules), NULL, NULL);
			if (iRet <= 0)
			{
				rpt += "获取拌线规则失败\n";
			}
//			CString temp = _T("");
//			temp.Format("获取\n警戒线\n规则条数:%d\n", g_dlgSmartBaseSet->m_singleRules.m_count);
//			rpt += temp;
//			for(int i = 0; i < g_dlgSmartBaseSet->m_singleRules.m_count; i++)
//			{
//				temp.Format("规则启用:%d.规则名称(长度%d):%s\n", g_dlgSmartBaseSet->m_singleRules.m_lines[i].m_enable,
//					strlen(g_dlgSmartBaseSet->m_singleRules.m_lines[i].m_rulename), g_dlgSmartBaseSet->m_singleRules.m_lines[i].m_rulename);
//				rpt += temp;
//			}
			iRet = VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_GETREGIONINRULE, m_ch, &g_dlgSmartBaseSet->m_regionInRule, NULL, NULL);
			if (iRet <= 0)
			{
				rpt += "获取区域侵入规则失败\n";
			}	
			iRet = VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_GETREGIONOUTRULE, m_ch, &g_dlgSmartBaseSet->m_regionOutRule, NULL, NULL);
			if (iRet <= 0)
			{
				rpt += "获取区域离开规则失败\n";
			}
			iRet = -1;
			iRet = VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_GETREGIONHOVERRULE, m_ch, &g_dlgSmartBaseSet->m_regionHoverRule, NULL, NULL);
			if (iRet <= 0)
			{
				rpt += "获取区域徘徊规则失败";
			}
			VSNET_ClientMessageClose(hParam);
		}
	}
	catch (...) {AfxMessageBox("...");}
	
	m_hMutexSet.Unlock();

    return iRet;
}

int CMyRulesStatic::GetRulesCount()
{
    int rulesCount = 0;

    rulesCount = m_rulesList.GetCount();

    return rulesCount;
}

int CMyRulesStatic::GetSingleLineRuleCount()
{
    int      count = 0;
    POSITION pos;
    CMyRule*   pRule;

    pos = m_rulesList.GetHeadPosition();
    while (pos)
    {
        pRule = (CMyRule*)m_rulesList.GetNext(pos);
        if (pRule->m_ruleType == RULE_TYPE_SINGLELINE)
            count += ((CSingleLineRule*)pRule)->GetLineCount();
    }

    return count;
}

void CMyRulesStatic::SetCurSelRuleByIndex(int index)
{

    POSITION    pos;
    
    pos = m_rulesList.FindIndex(index);
    if (pos)
    {
        CMyRule*  pRule = (CMyRule*)m_rulesList.GetAt(pos);
        if (pRule != m_pSelectRule)
        {
            m_pSelectRule = pRule;
            if (m_pSelectRule->m_ruleType == RULE_TYPE_REGION)
            {
                m_bRegionRectValid = FALSE;
                m_region_tmp_count = 0;
            }
			if(m_pSelectRule->m_ruleType == RULE_TYPE_SINGLELINE)
			{
				CSingleLineRule *pSingle = (CSingleLineRule*)pRule;
				if(pSingle->GetLineCount() <= 0)
					pSingle->m_bInitDraw = FALSE;
			}
            RefreshWindow();
        }
    }
	
}

BOOL CMyRulesStatic::CopyRule(int index,int curcount)
{
    POSITION pos = NULL;
    CMyRule*   pRule = NULL;
    CMyRule*   pNewRule = NULL;
	CString    pRuleName;

    pos = m_rulesList.FindIndex(index);
    if (pos == NULL)
    {
        return FALSE;
    }
    pRule = (CMyRule*)m_rulesList.GetAt(pos);

    if (pRule->m_ruleType == NEWRULE_TYPE_SINGLELINE)
    {
        //添加单线和折线规则
		if(((CSingleLineRule*)pRule)->m_bMultiSegment)
			pRuleName.Format("多段绊线规则%d",curcount + 1);
		else
			pRuleName.Format("绊线规则%d",curcount + 1);
        pNewRule = AddSingleLineRule(((CSingleLineRule*)pRule)->m_bMultiSegment, (CSingleLineRule*)pRule,
			pRuleName.GetBuffer(0));
    }
    else if (pRule->m_ruleType == RULE_TYPE_DOUBLELINE)
    {
        //添加折线规则
		pRuleName.Format("双线规则%d",curcount + 1);
        pNewRule = AddDoubleLineRule((CDoubleLineRule*)pRule,pRuleName.GetBuffer(0));
    }
    else
    {
        ::AfxMessageBox("复制区域规则失败!");
    }
    return pNewRule != NULL;
}

CMyRule* CMyRulesStatic::GetRuleByIndex(int index)
{
    POSITION pos;
    CMyRule*   pRule = NULL;

    pos = m_rulesList.FindIndex(index);
    if (pos)
    {
        pRule = (CMyRule*)m_rulesList.GetAt(pos);
    }

    return pRule;
}

void CMyRulesStatic::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
    switch (m_editActionType)
    {
    case EDITRULE_ACTION_MOVE:
    case EDITRULE_ACTION_MOVEING:
        ::SetCursor(m_hCursorMove);
        break;
    case EDITRULE_ACTION_HOTPOINT:
    case EDITRULE_ACTION_OBJECT_MIN_AREAING:
    case EDITRULE_ACTION_OBJECT_MAX_AREAING:
    case EDITRULE_ACTION_REGION_POLYGONOVER:
        ::SetCursor(m_hCursorCross);
        break;
    case EDITRULE_ACTION_PENCIL:
    case EDITRULE_ACTION_PENCILING:
	case EDITRULE_ACTION_REGION_RECT:
	case EDITRULE_ACTION_REGION_RECTING:
	case EDITRULE_ACTION_REGION_POLYGON:
	case EDITRULE_ACTION_REGION_POLYGONING:
        ::SetCursor(m_hCursorPencil);
        break;
    case EDITRULE_ACTION_ERASE:
    case EDITRULE_ACTION_ERASEING:
        ::SetCursor(m_hCursorErase);
        break;
    case EDITRULE_ACTION_REGION_FILL:
        ::SetCursor(m_hCursorFill);
        break;       
    case EDITRULE_ACTION_NONE:
    case EDITRULE_ACTION_OBJECT_MIN_AREA:
    case EDITRULE_ACTION_OBJECT_MAX_AREA:
    default:
        ::SetCursor(m_hCursorArrow);
        break;
    }
}

void CMyRulesStatic::RefreshWindow(LPCRECT lpRect)
{
    InvalidateRect(NULL);
    UpdateWindow();
}

int CMyRulesStatic::GetRegionRuleCount(int regionDrc)
{
    int      count = 0;
    POSITION pos;
    CMyRule*   pRule;

    pos = m_rulesList.GetHeadPosition();
    while (pos)
    {
        pRule = (CMyRule*)m_rulesList.GetNext(pos);
        if (pRule->m_ruleType == RULE_TYPE_REGION && ((CRegionRule*)pRule)->m_regionDrc == regionDrc )
            count++;
    }

    return count;
}

void CMyRulesStatic::SetEditActionType(int editAction)
{
    m_editActionType = editAction;
}

void CMyRulesStatic::RegionCleanAll()
{
    CRegionRule   *pRegionRule; 
    pRegionRule = m_bEditShieldMsk?&m_rule_shield_msk:(CRegionRule*)m_pSelectRule;

    pRegionRule->CleanAllRegion();
    RefreshWindow();
}

void CMyRulesStatic::AddRegionPolyPoint(CPoint point)
{
    m_region_tmp_polygon_point[m_region_tmp_count].x = point.x;
    m_region_tmp_polygon_point[m_region_tmp_count].y = point.y;

    m_region_tmp_count++;
}

BOOL CMyRulesStatic::PtInPolygon(CPoint point)
{
    CRgn    tmpRgn;

    tmpRgn.CreatePolygonRgn(m_region_tmp_polygon_point,m_region_tmp_count,WINDING);
    return tmpRgn.PtInRegion(point);
}

int CMyRulesStatic::ChangeRegionLineWidth(int index)
{
	m_lineWidth = index;
    return m_lineWidth;
}

void CMyRulesStatic::DrawRegion(CDC* pDC, CRgn *pRgn, CBrush *pBkBrush, COLORREF bkColor)
{
    CDC             memDC;
    CBitmap         memBitmap;
    CBitmap         *pOldBitmap;
    CRect           rc; 
    BLENDFUNCTION   bf;

    if (!memDC.CreateCompatibleDC(NULL))
    {
        return;
    }
  
    GetClientRect(&rc);
	if (rc.left < 0 || rc.right < 0 || rc.bottom < 0 || rc.top < 0)
	{
		return;
	}
    memBitmap.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());
    pOldBitmap = memDC.SelectObject(&memBitmap);

    memDC.SetBkColor(bkColor);
    memDC.FillRgn(pRgn, pBkBrush);

    bf.BlendOp		        =  AC_SRC_OVER;   
	bf.BlendFlags	        =  0;   
	bf.SourceConstantAlpha  =  40; 
	bf.AlphaFormat	        =  0;   
	AlphaBlend(pDC->m_hDC, rc.left, rc.top, rc.Width(), rc.Height(), memDC.m_hDC, 0, 0, rc.Width(), rc.Height(), bf);

    memDC.SelectObject(pOldBitmap);
    memBitmap.DeleteObject();
    memDC.DeleteDC();
}


void CMyRulesStatic::DrawRegionRule(CDC *pDC)
{
    DrawRegion(pDC, &((CRegionRule*)m_pSelectRule)->m_rgn, &m_brush_rule_region, RGB(0,255,0));

    if (m_bRegionRectValid)
    {
        HBRUSH  hOldBrush;
        CPen    *pOldPen;
        
        pOldPen   = pDC->SelectObject(&m_pen_normal_line);
        hOldBrush = (HBRUSH)pDC->SelectObject(GetStockObject(NULL_BRUSH));
        pDC->Rectangle(m_region_tmp_rect);
        pDC->SelectObject(&pOldPen);
        pDC->SelectObject(hOldBrush);
    }

    if( m_region_tmp_count > 0 )
    {
        CPen    *pOldPen;

        pOldPen  = pDC->SelectObject(&m_pen_normal_line);
        pDC->MoveTo(m_region_tmp_polygon_point[0].x,m_region_tmp_polygon_point[0].y);
        for(int index=1; index<m_region_tmp_count; index++)
        {
            pDC->LineTo(m_region_tmp_polygon_point[index].x,m_region_tmp_polygon_point[index].y);
        }
        pDC->SelectObject(&pOldPen);
    }
}

BOOL CMyRulesStatic::SaveRuelsSettings()
{
    //BOOL  iRet = FALSE;
    LONG  hParam;
	CString rpt = "";
    m_hMutexSet.Lock();
	try
	{
		hParam = VSNET_ClientMessageOpen((char*)(LPCTSTR)m_szDevname,  (char*)(LPCTSTR)m_szUrl, 
										 (char*)(LPCTSTR)m_szUsername, (char*)(LPCTSTR)m_szPassword, m_port);
		if (hParam)
		{   
			VSNET_ClientMessageOpt(hParam,MESSAGE_CMD_SETALARMLINERULES,m_ch,&g_dlgSmartBaseSet->m_singleRules,NULL,NULL);
			VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_SETREGIONINRULE, m_ch, &g_dlgSmartBaseSet->m_regionInRule, NULL,NULL);
			VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_SETREGIONOUTRULE, m_ch, &g_dlgSmartBaseSet->m_regionOutRule, NULL, NULL);
			VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_SETREGIONHOVERRULE, m_ch, &g_dlgSmartBaseSet->m_regionHoverRule, NULL, NULL);
			VSNET_ClientMessageClose(hParam);
		}
	}
	catch (...) {}
	m_hMutexSet.Unlock();
    return TRUE;
}

int CMyRulesStatic::GetLineWidth()
{
    return m_lineWidth;
}

void CMyRulesStatic::EditShieldMskRegion(BOOL bEditShieldMsk)
{
    m_bEditShieldMsk = bEditShieldMsk;
}

void CMyRulesStatic::LoadVAParam(int &iRet1, int &iRet2, int &iRet3)
{
	LONG  hParam;

	m_hMutexSet.Lock();
	try
	{
		memset(&m_vabackground, 0, sizeof(VSNETVABACKGROUND));
		memset(&m_vaobjectarea, 0, sizeof(VSNETVAOBJECTAREA));
		memset(&m_vaalarmsettings, 0, sizeof(VSNETVAALARMSETTING));

		hParam = VSNET_ClientMessageOpen((char*)(LPCTSTR)m_szDevname,  (char*)(LPCTSTR)m_szUrl, 
										 (char*)(LPCTSTR)m_szUsername, (char*)(LPCTSTR)m_szPassword, m_port);

		if (hParam)
		{
			iRet1 = VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_GETVABACKGROUND, 
										  m_ch, &m_vabackground);

			iRet2 = VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_GETVAOBJECTAREA, 
										  m_ch, &m_vaobjectarea);

			iRet3 = VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_GETVAALARMSETTING, 
										  m_ch, &m_vaalarmsettings);

			if (iRet3)
			{
				memcpy(&m_rule_shield_msk.m_Rule.m_packed_msk, &m_vaalarmsettings.m_region_shield_msk, sizeof(m_vaalarmsettings.m_region_shield_msk));
				m_rule_shield_msk.CreateRgnFromRule();
			}

			VSNET_ClientMessageClose(hParam);
		}
	}
	catch (...) {}
}

BOOL CMyRulesStatic::SaveVAParam(BOOL bSet)
{
	BOOL  iRet = FALSE;
    LONG  hParam;
	
	m_hMutexSet.Lock();
	try
	{
		hParam = VSNET_ClientMessageOpen((char*)(LPCTSTR)m_szDevname,  (char*)(LPCTSTR)m_szUrl, 
										 (char*)(LPCTSTR)m_szUsername, (char*)(LPCTSTR)m_szPassword, m_port);

		if (!hParam)
		{
			return FALSE;
		}
		
		if(!bSet)
		{
			VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_SETVABACKGROUND, 
									m_ch, &m_vabackground);
		}
		else
		{
			VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_SETVAOBJECTAREA, 
				m_ch, &m_vaobjectarea);
			
			m_rule_shield_msk.GetRuleFromRgn((UINT*)&m_vaalarmsettings.m_region_shield_msk);
			int iRet = VSNET_ClientMessageOpt(hParam, MESSAGE_CMD_SETVAALARMSETTING, 
				m_ch, &m_vaalarmsettings);
		}
		

		VSNET_ClientMessageClose(hParam);

	}
	catch (...) {}
	m_hMutexSet.Unlock();
	
    return TRUE;
}
int CMyRulesStatic::GetMultiLineRuleCount()
{
	return m_multilinecount;
}
void CMyRulesStatic::SetCurRule(CMyRule* curRule)
{
	if (m_pSelectRule)
	{
		delete m_pSelectRule;
		m_pSelectRule = NULL;
	}
	m_pSelectRule = curRule;
}

void CMyRulesStatic::InitValue()
{
    if (m_pSelectRule != NULL)
    {
        delete m_pSelectRule;
        m_pSelectRule = NULL;
    }

    m_editActionType  = EDITRULE_ACTION_NONE;

    m_bRegionRectValid= FALSE;
    m_region_tmp_rect = CRect(0, 0, 0, 0);

    for (int index=0; index<REGION_POLYGON_MAXCOUNT; index++)
    {
        m_region_tmp_polygon_point[index].x = 0;
        m_region_tmp_polygon_point[index].y = 0;
    }
    m_region_tmp_count = 0;

    m_lineWidth = 1;

    m_object_min_area = CRect(0, 0, 0, 0);
    m_object_max_area = CRect(0, 0, 0, 0);

    m_bEditShieldMsk  = FALSE;
	m_multilinecount  = 0;
}

void CMyRulesStatic::EnableEdit(BOOL bEnable)
{
    m_bEnableEdit = bEnable;
}

LONG CMyRulesStatic::MessageOpen()
{
	return VSNET_ClientMessageOpen(m_szDevname.GetBuffer(0),m_szUrl.GetBuffer(0),
		m_szUsername.GetBuffer(0),m_szPassword.GetBuffer(0),m_port);
}

int CMyRulesStatic::MessageOpt(LONG handle,int opt,void* param1,void* param2,void*param3)
{
	return VSNET_ClientMessageOpt(handle,opt,0,param1,param2,param3);
}

BOOL CMyRulesStatic::MessageClose(LONG handle)
{
	return VSNET_ClientMessageClose(handle);
}