// paintView.cpp : CpaintView 클래스의 구현

#include "stdafx.h"
#include "paint.h"
#include "Data.h"
#include "paintDoc.h"
#include "paintView.h"
// #include "DrawRect.h"
// #include "DrawElli.h"
// #include "DrawLine.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CpaintView

IMPLEMENT_DYNCREATE(CpaintView, CView)

BEGIN_MESSAGE_MAP(CpaintView, CView)
	// 표준 인쇄 명령입니다.
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_COMMAND(ID_SELECT, &CpaintView::OnSELECT)
	ON_COMMAND(ID_LINE, &CpaintView::OnLINE)
	ON_COMMAND(ID_RECT, &CpaintView::OnRECT)
	ON_COMMAND(ID_ELLI, &CpaintView::OnELLI)
	ON_COMMAND(ID_BTN_LINERGB, &CpaintView::OnBtnLinergb)
	ON_COMMAND(ID_BTN_PLUS, &CpaintView::OnBtnPlus)
	ON_COMMAND(ID_BTN_MINUS, &CpaintView::OnBtnMinus)
	ON_COMMAND(ID_STR_2, &CpaintView::OnSTR_2)
	ON_COMMAND(ID_STR_3, &CpaintView::OnSTR_3)
	ON_COMMAND(ID_STR_4, &CpaintView::OnSTR_4)
	ON_COMMAND(ID_STR_5, &CpaintView::OnSTR_5)
	ON_COMMAND(ID_STR_6, &CpaintView::OnSTR_6)
	//ON_COMMAND(ID_STR_7, &CpaintView::OnSTR_7)
	ON_COMMAND(ID_STR_8, &CpaintView::OnSTR_8)
	ON_COMMAND(ID_STR_9, &CpaintView::OnSTR_9)
	//ON_COMMAND(ID_32855, &CpaintView::On32855)
	ON_COMMAND(ID_STR_1, &CpaintView::OnSTR_1)
	ON_UPDATE_COMMAND_UI(ID_LINE, &CpaintView::OnUpdateLine)
	ON_UPDATE_COMMAND_UI(ID_SELECT, &CpaintView::OnUpdateSelect)
	ON_UPDATE_COMMAND_UI(ID_RECT, &CpaintView::OnUpdateRECT)
	ON_UPDATE_COMMAND_UI(ID_ELLI, &CpaintView::OnUpdateELLI)
	ON_COMMAND(ID_BTN_ptRGB, &CpaintView::OnBtnptrgb)
	ON_COMMAND(ID_STR_7, &CpaintView::OnStr7)
	ON_COMMAND(ID_STR_10, &CpaintView::OnStr10)
	ON_COMMAND(ID_POLY, &CpaintView::OnPoly)
	ON_WM_LBUTTONDBLCLK()
	ON_UPDATE_COMMAND_UI(ID_POLY, &CpaintView::OnUpdatePoly)
	ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()

// CpaintView 생성/소멸

CpaintView::CpaintView()
{
	// TODO: 여기에 생성 코드를 추가합니다.
	memset(&m_logFont, 0 , sizeof(LOGFONT));
	
	m_memDC = NULL;
	m_bitmap = NULL;
	m_pDrawList = CData::GetInstance();
	m_penColor=RGB(0,0,0);
	m_LineSize2 = 1;
	m_brush = RGB(255,255,255);
	m_bDrawMode = FALSE;
	m_bLButtonDown = FALSE;



}

CpaintView::~CpaintView()
{	

	delete m_memDC;
	delete m_bitmap;
	

}

BOOL CpaintView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: CREATESTRUCT cs를 수정하여 여기에서
	//  Window 클래스 또는 스타일을 수정합니다.

	return CView::PreCreateWindow(cs);
}

void CpaintView::OnInitialUpdate() 
{
	m_memDC = new CDC();
	m_bitmap = new CBitmap();

	// 	GetClientRect(_rect);
	// 	CClientDC dc(this);

	m_memDC->CreateCompatibleDC(GetDC());
	m_bitmap->CreateCompatibleBitmap(GetDC(), m_rect.Width(), m_rect.Height());

	m_oldBitmap = m_memDC->SelectObject(m_bitmap);
	
	
}

// CpaintView 그리기

void CpaintView::OnDraw(CDC* pDC)
{

	CpaintDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	// TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.

	CRect rect;
	CRect rec/*, rect*/;
	GetClientRect(rec);

	pDC->GetClipBox(&rect);

	//	CMFCDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	m_oldBitmap = m_memDC->SelectObject(m_bitmap);
	CGdiObject* old    = m_memDC->SelectStockObject(NULL_BRUSH);
	CGdiObject* oldPen = m_memDC->SelectStockObject(WHITE_PEN);
	m_memDC->Rectangle(rec);
	m_memDC->SelectObject(oldPen);

	CPtrList* list = &pDoc->getDrawObjects();

	POSITION pos = list->GetHeadPosition();
	while (pos != NULL) 
	{
		((CData*)list->GetNext(pos))->OnDraw(pDC);
	}


	pDC->BitBlt(0, 0, rect.Width(), rect.Height(), m_memDC, 0, 0, SRCCOPY);

	m_memDC->SelectObject(old);
	m_memDC->SelectObject(m_oldBitmap);

}
// CpaintView 인쇄

BOOL CpaintView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 기본적인 준비
	return DoPreparePrinting(pInfo);
}

void CpaintView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 인쇄하기 전에 추가 초기화 작업을 추가합니다.
}

void CpaintView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 인쇄 후 정리 작업을 추가합니다.
}


// CpaintView 진단

#ifdef _DEBUG
void CpaintView::AssertValid() const
{
	CView::AssertValid();
}

void CpaintView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CpaintDoc* CpaintView::GetDocument() const // 디버그되지 않은 버전은 인라인으로 지정됩니다.
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CpaintDoc)));
	return (CpaintDoc*)m_pDocument;
}
#endif //_DEBUG


// CpaintView 메시지 처리기

void CpaintView::OnLButtonDown(UINT nFlags, CPoint point)
{
	m_bDrawMode = TRUE;
	
	CpaintDoc* pDoc = GetDocument();
	CClientDC pDC(this);
	//각변수 초기화
// 	if(m_bFirst)
// 	{
// 		m_ptStart = m_ptPrev = 0;
// 		m_bLButtonDown = FALSE;
// 	
// //		Invalidate(true);
// 	
// 	}

		if (m_pDrawList-> m_Dtype == POLYLINE)
		{		
			pDoc->CreateObj( m_pDrawList->m_Dtype );
			pDoc->m_CurDraw->OnLBDN(point);
			m_ptStart = m_ptPrev = point;
		}
		else
		{
			m_ptStart = m_ptPrev = point;
			pDoc->CreateObj( m_pDrawList->m_Dtype );
			pDoc->m_CurDraw->OnLBDN(point);
			/*m_bFirst = FALSE;*/
			m_bLButtonDown = TRUE;
//			Invalidate(TRUE);
			
		}

		CView::OnLButtonDown(nFlags, point); 
}
//Invalidate();
void CpaintView::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
	
	
	CpaintDoc* pDoc = GetDocument();
	CClientDC pDC(this);
	if (m_bDrawMode)
	{
		
			CClientDC dc(this);
			dc.SelectStockObject(NULL_BRUSH);
			CPen pen;
			CPen m_penDot(PS_DOT, 1, RGB(0, 0, 0));
			dc.SelectObject(&m_penDot);
			//if(nFlags == MK_LBUTTON)  
		
			if(m_pDrawList -> m_Dtype == LINE)
			{	
				if(m_bLButtonDown)
				{
					dc.SetROP2(R2_XORPEN);
					dc.MoveTo(m_ptStart);
					dc.LineTo(m_ptPrev);	
					pen.DeleteObject(); 
					dc.MoveTo(m_ptStart);//이 2문장이 중복되게 그려지는걸제거해줍니다.
					dc.LineTo(point);
					m_ptPrev = point;
				}
							
				
			}
			if(m_pDrawList -> m_Dtype == RECTANGLE)
			{
				if(m_bLButtonDown)
				{
					dc.SetROP2(R2_XORPEN);
					// 이전에 그린 직선을 지운다.
					dc.Rectangle(m_ptStart.x,m_ptStart.y,m_ptPrev.x,m_ptPrev.y);
					// 새로운 직선을 그린다.
					dc.Rectangle(m_ptStart.x,m_ptStart.y,point.x,point.y);
					// 직선 끝점의 좌표를 갱신한다.
					m_ptPrev = point;
					//Invalidate();
				}
					//drawRectMove(point);
			}
			if(m_pDrawList -> m_Dtype == ELLIPSE)
			{
				if(m_bLButtonDown)
				{
					dc.SetROP2(R2_XORPEN);
					dc.Ellipse(m_ptStart.x,m_ptStart.y,m_ptPrev.x,m_ptPrev.y);
					// 그리기 모드를 해제한다.
					dc.Ellipse(m_ptStart.x,m_ptStart.y,point.x,point.y);
					m_ptPrev = point;

				}
			}		
			if(m_pDrawList -> m_Dtype == POLYLINE)
			{					
				if(m_pDrawList->m_bFirst = TRUE)
				{
					dc.SetROP2(R2_NOT);
					dc.MoveTo(m_ptStart);
					dc.LineTo(m_ptPrev);

					dc.MoveTo(m_ptStart);
					dc.LineTo(point);
					m_ptPrev = point;
				}
			}
			
			//Invalidate();
	
	}
	::ReleaseCapture();
	//Invalidate(FALSE);

	CView::OnMouseMove(nFlags, point);
}

void CpaintView::OnLButtonUp(UINT nFlags, CPoint point)
{

	CpaintDoc* pDoc = GetDocument();	
	CClientDC pDC(this);

	if(m_bLButtonDown)
	{
		if(m_pDrawList->m_Dtype == LINE ||m_pDrawList->m_Dtype == RECTANGLE||m_pDrawList->m_Dtype == ELLIPSE)
		{
			m_bLButtonDown = false;
			
			//ReleaseCapture(true);
			::ClipCursor(NULL);
			Invalidate();
			pDoc -> m_CurDraw -> OnLBUP(point);
			pDoc -> m_CurDraw -> Attri(m_LineSize2);
			pDoc -> m_CurDraw -> m_RGB(m_penRGB,m_brush);
		}
	}
	ReleaseCapture();
	::ClipCursor(NULL);
	
}


void CpaintView::OnSELECT() //선택
{
	// TODO: 여기에 명령 업데이트 UI 처리기 코드를 추가합니다.
	m_pDrawList ->m_Dtype = 0;
	mode1 = 0;
}

void CpaintView::OnLINE() //선
{
	// TODO: 여기에 명령 업데이트 UI 처리기 코드를 추가합니다.
	m_pDrawList ->m_Dtype = 1;
	mode1 = 1;

}
//==================================================================================
//사각형

void CpaintView::OnRECT()
{
	m_pDrawList ->m_Dtype = 2;
	mode1 = 2;
}


void CpaintView::OnPoly()
{
	m_pDrawList->m_Dtype = 5;
	mode1 =5;

}


void CpaintView::OnELLI()
{
	m_pDrawList->m_Dtype = 3;
	mode1 = 3;
	// TODO: 여기에 명령 업데이트 UI 처리기 코드를 추가합니다.
}

//==================================================================================
void CpaintView::OnUpdate(CView* pSender,LPARAM lHint, CObject* pHint)
{
	if(lHint = 0)
	{
			CRect rectTrue;
			CpaintDoc* pDoc = GetDocument();
//			pDoc->m_tracker.GetTrueRect(&rectTrue);
			InvalidateRect(rectTrue);
	}
	else
	{
		InvalidateRect((CRect*)lHint);
	}

}


//==================================================================================================================================
//색채우기

void CpaintView::OnBtnLinergb()
{
	CColorDialog dlg;	
	if(dlg.DoModal() ==IDOK)
	{
		m_penRGB = dlg.GetColor();
	}
	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}
void CpaintView::OnBtnptrgb()
{
	CColorDialog dlg;	
	if(dlg.DoModal() ==IDOK)
	{
		m_brush = dlg.GetColor();
	}		
	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}



//Mode선택==========================================================
void CpaintView::OnBtnPlus()
{
	if(m_LineSize2<11)
	{
		 m_LineSize2++;
		
	}
	else
	{
		m_LineSize2 = 10;
	}

	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}

void CpaintView::OnBtnMinus()
{
	if(m_LineSize2>1)
	{
		 m_LineSize2--;
	}
	else
	{
		 m_LineSize2 = 1;
	}


	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}

void CpaintView::OnSTR_2()
{
	 m_LineSize2 = 2;
	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}

void CpaintView::OnSTR_3()
{
	m_LineSize2 = 3;
	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}

void CpaintView::OnSTR_4()
{
	 m_LineSize2 = 4;
	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}

void CpaintView::OnSTR_5()
{
	 m_LineSize2 = 5;
	
	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}

void CpaintView::OnSTR_6()
{
	m_LineSize2 = 6;
	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}

void CpaintView::OnStr7()
{

	m_LineSize2 = 7;
	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}

void CpaintView::OnSTR_8()
{
	 m_LineSize2 = 8;
	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}

void CpaintView::OnSTR_9()
{
	 m_LineSize2 = 9;
	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}

void CpaintView::OnSTR_1()
{
	m_LineSize2 = 1;
	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}

void CpaintView::OnStr10()
{

	m_LineSize2 = 10;
	// TODO: 여기에 명령 처리기 코드를 추가합니다.
}




//====================================================================
//Check

void CpaintView::OnUpdateLine(CCmdUI *pCmdUI)
{
		
	if(mode1 == 1)
	{
		pCmdUI->SetCheck();

	}
	else
	{
		pCmdUI->SetCheck(FALSE);
	}

	// TODO: 여기에 명령 업데이트 UI 처리기 코드를 추가합니다.
}

void CpaintView::OnUpdateSelect(CCmdUI *pCmdUI)
{
	if(mode1 ==0){
		pCmdUI->SetCheck();

	}
	else{
		pCmdUI->SetCheck(FALSE);
	}
	// TODO: 여기에 명령 업데이트 UI 처리기 코드를 추가합니다.
}

void CpaintView::OnUpdateRECT(CCmdUI *pCmdUI)
{
	if(mode1 == 2){
		pCmdUI->SetCheck();

	}
	else{
		pCmdUI->SetCheck(FALSE);
	}
	// TODO: 여기에 명령 업데이트 UI 처리기 코드를 추가합니다.
}
void CpaintView::OnUpdateELLI(CCmdUI *pCmdUI)
{
	if(mode1 ==3){
		pCmdUI->SetCheck();

	}
	else{
		pCmdUI->SetCheck(FALSE);
	}
	// TODO: 여기에 명령 업데이트 UI 처리기 코드를 추가합니다.
}


void CpaintView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	CpaintDoc* pDoc = GetDocument();	
 	pDoc -> m_CurDraw -> OnLBDC(point);

}

void CpaintView::OnUpdatePoly(CCmdUI *pCmdUI)
{

	if(mode1 ==5)
	{
		pCmdUI->SetCheck();
	}
	else
	{
		pCmdUI->SetCheck(FALSE);
		m_bcli = FALSE;
	}	
	// TODO: 여기에 명령 업데이트 UI 처리기 코드를 추가합니다.
}

