/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/* ***************************************************** */

#include "stdafx.h"
#include "mgGL/Color.h"
#include "mgGL/LineStipple.h"
#include "mgGL/LineWidth.h"
#include "mgGL/Appearance.h"
#include "mg/PickObjects.h"
#include "fugen.h"
#include "fugenDoc.h"
#include "GLColorLineAttribPage.h"

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

/////////////////////////////////////////////////////////////////////////////
// CGLColorLineAttribPage

IMPLEMENT_DYNCREATE(CGLColorLineAttribPage, CPropertyPage)

CGLColorLineAttribPage::CGLColorLineAttribPage()
	 : CPropertyPage(CGLColorLineAttribPage::IDD),
	   m_dwColor(MGColor::get_ARGBinstance(MGColor::Black)),
	   m_dwColorOther(MGColor::get_ARGBinstance(MGColor::White)),
	   m_useContextColor(TRUE),
	   m_nColorId(MGColor::dummy),
	   m_line_width_context(BST_CHECKED),
	   m_fLineWidth(1.0f),
	   m_line_stipple_context(TRUE),
	   m_nStipplePreset(0),
	   m_iStippleFactor(1),
	   m_shStipplePattern(0x5555),
	   m_bCustomStipple(FALSE)
{
}

CGLColorLineAttribPage::~CGLColorLineAttribPage(){
}

void CGLColorLineAttribPage::DoDataExchange(CDataExchange* pDX){
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CGLColorLineAttribPage)
	DDX_Control(pDX, IDC_COMBO_COLOR, m_cbxColor);
	DDX_Check(pDX, IDC_CHECK_CONTEXT_COLOR, m_useContextColor);
	DDX_Check(pDX, IDC_LINE_ATTR, m_line_width_context);
	DDX_Check(pDX, IDC_CHECK_STIPPLE, m_line_stipple_context);
	DDX_Text(pDX, IDC_EDIT_LINEWIDTH, m_fLineWidth);
	DDV_MinMaxFloat(pDX, m_fLineWidth, 0.001f, 99999.99f);
	DDX_CBIndex(pDX, IDC_COMBO_STIPPLE_PRESET, m_nStipplePreset);
	DDX_Check(pDX, IDC_CHECK_STIPPLE_CUSTOM, m_bCustomStipple);
	DDX_Text(pDX, IDC_EDIT_STIPPLE_FACTOR, m_iStippleFactor);
	DDV_MinMaxInt(pDX, m_iStippleFactor, 1, 999999);
	//}}AFX_DATA_MAP

	if(pDX->m_bSaveAndValidate){
		// 16 進数を読み込む
		CString strVal;
		GetDlgItemText(IDC_EDIT_STIPPLE_PATTERN, strVal);
		if(_stscanf_s(strVal, _T("%hx"), &m_shStipplePattern) == EOF){
			//AfxMessageBox("16 進数を入力してください");
			pDX->Fail();
		}
	}else{
		// 16 進数で表現する。
		CString strVal;
		strVal.Format(_T("0x%04X"), m_shStipplePattern);
		SetDlgItemText(IDC_EDIT_STIPPLE_PATTERN, strVal);
	}
}

BEGIN_MESSAGE_MAP(CGLColorLineAttribPage, CPropertyPage)
	//{{AFX_MSG_MAP(CGLColorLineAttribPage)
	ON_BN_CLICKED(IDC_BUTTON_COLOR, OnAttribColorOther)
	ON_CBN_SELCHANGE(IDC_COMBO_COLOR, OnAttribColor)
	ON_BN_CLICKED(IDC_CHECK_STIPPLE_CUSTOM, OnBnClickedLineAttr)
	ON_BN_CLICKED(IDC_CHECK_CONTEXT_COLOR, OnBnClickedContextColor)
	ON_BN_CLICKED(IDC_CHECK_STIPPLE, OnBnClickedLineAttr)
	ON_BN_CLICKED(IDC_LINE_ATTR, OnBnClickedLineAttr)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

MGColor* CGLColorLineAttribPage::CreateColor() const{
	return new MGColor(m_dwColor);
}
MGColor CGLColorLineAttribPage::GetColor()const{
	return MGColor(m_dwColor);
}

MGLineStipple* CGLColorLineAttribPage::CreateLineStipple() const{
	MGLineStipple* ls = 0;
	if(m_line_stipple_context){
		ls = new MGLineStipple;
		ls->set_disabled();
	}
	else if(m_bCustomStipple){
		ls = new MGLineStipple;
		ls->set(m_iStippleFactor, m_shStipplePattern);
	}
	else{
		ls = new MGLineStipple(MGLineStipple::LineFont(m_nStipplePreset + 1));
	}
	return ls;
}

MGLineStipple CGLColorLineAttribPage::GetLineStipple() const{
	return MGLineStipple(MGLineStipple::LineFont(m_nStipplePreset + 1));
}

MGLineWidth* CGLColorLineAttribPage::CreateLineWidth() const{
	return new MGLineWidth(m_fLineWidth);
}

MGLineWidth CGLColorLineAttribPage::GetLineWidth() const{
	return MGLineWidth(m_fLineWidth);
}

void CGLColorLineAttribPage::InitAttrib(const MGPickObjects& pobjs, fugenDoc* pDoc){
	if(pobjs.size() != 1) return;

	m_useContextColor = TRUE;
	const MGColor& gcolor=pDoc->context()->Gcolor();
	m_contextColor=gcolor.get_colorAsUInt();

	const MGPickObject& pobj = pobjs.front();
	const MGObject* obj = pobj.top_object();
	const MGAppearance* appe = obj->appearance();
	if(appe){
		MGAppearance::const_iterator i = appe->search_by_id(MGCOLOR_TID);
		if(i!=appe->end()){
			MGColor* lineColor = static_cast<MGColor*>(i->get());
			m_nColorId=lineColor->getColorIdOrValue(8,m_dwColorOther);
			m_useContextColor = FALSE;
		}

		i = appe->search_by_id(MGLINE_STIPPLE_TID);
		if(i != appe->end()){
			const MGLineStipple* ls = static_cast<MGLineStipple*>(i->get());
			//線種が有効な場合読み取り
			if(!(m_line_stipple_context = !ls->enabled())){
				m_iStippleFactor = ls->get_factor();
				m_shStipplePattern = ls->get_pattern();
			
				MGLineStipple::LineFont font = ls->get_font_number();
				if(!(m_bCustomStipple = (MGLineStipple::UndefinedFont == font)))
					m_nStipplePreset = font - 1;//コンボボックスの中身はenumの定義順
			}
		}

		i = appe->search_by_id(MGLINE_WIDTH_TID);
		if(i != appe->end()){
			const MGLineWidth* lw = static_cast<MGLineWidth*>(i->get());
			m_fLineWidth = lw->get_width();
			m_line_width_context = BST_UNCHECKED;
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
// CGLColorLineAttribPage

void CGLColorLineAttribPage::OnAttribColorOther(){
	CColorDialog dlg;
	if(IDOK == dlg.DoModal()){
		COLORREF cl = dlg.GetColor();
		int nIndex = m_cbxColor.GetCount() - 2;
		m_dwColorOther = COLORREFtoARGB(cl) | 0xFF000000;
		m_cbxColor.SetItemData(nIndex, m_dwColorOther);
		m_cbxColor.SetCurSel(nIndex);
		m_cbxColor.Invalidate();
	}
	UpdateData(FALSE);
}

void CGLColorLineAttribPage::OnAttribColor(){//IDC_COMBO_COLOR
	if(m_cbxColor.GetCurSel() == m_cbxColor.GetCount()-2){//If other color.
		OnAttribColorOther();
	}else if(m_cbxColor.GetCurSel() == m_cbxColor.GetCount()-1){//If context color
		m_useContextColor=TRUE;
	}
}

#define OTHER_COLOR_ITEM_ID 8
#define CONTEXT_COLOR_ITEM_ID 9
BOOL CGLColorLineAttribPage::OnInitDialog(){
	CPropertyPage::OnInitDialog();
	// 1 - Init color combo box.
	m_cbxColor.InitStorage(10, 16);//from Black to m_dwColorOther + Context color=10 items.

	int i = 0;
	CString str;
//	VERIFY(str.LoadString(IDS_ATTRIB_LAYER_COLOR));
//	m_cbxColor.AddString(str);
//	m_cbxColor.SetItemData(i++, MGColor::BlackV);

	VERIFY(str.LoadString(IDS_COLOR_BLACK));
	m_cbxColor.AddString(str);
	m_cbxColor.SetItemData(i++, MGColor::get_ARGBinstance(MGColor::Black));//0

	VERIFY(str.LoadString(IDS_COLOR_RED));
	m_cbxColor.AddString(str);
	m_cbxColor.SetItemData(i++, MGColor::get_ARGBinstance(MGColor::Red));//1

	VERIFY(str.LoadString(IDS_COLOR_GREEN));
	m_cbxColor.AddString(str);
	m_cbxColor.SetItemData(i++, MGColor::get_ARGBinstance(MGColor::Green));//2

	VERIFY(str.LoadString(IDS_COLOR_BLUE));
	m_cbxColor.AddString(str);
	m_cbxColor.SetItemData(i++, MGColor::get_ARGBinstance(MGColor::Blue));//3

	VERIFY(str.LoadString(IDS_COLOR_YELLOW));
	m_cbxColor.AddString(str);
	m_cbxColor.SetItemData(i++, MGColor::get_ARGBinstance(MGColor::Yellow));//4

	VERIFY(str.LoadString(IDS_COLOR_MAGENTA));
	m_cbxColor.AddString(str);
	m_cbxColor.SetItemData(i++, MGColor::get_ARGBinstance(MGColor::Magenta));//5

	VERIFY(str.LoadString(IDS_COLOR_CYAN));
	m_cbxColor.AddString(str);
	m_cbxColor.SetItemData(i++, MGColor::get_ARGBinstance(MGColor::Cyan));//6

	VERIFY(str.LoadString(IDS_COLOR_WHITE));
	m_cbxColor.AddString(str);
	m_cbxColor.SetItemData(i++, MGColor::get_ARGBinstance(MGColor::White));//7

	VERIFY(str.LoadString(IDS_COLOR_OTHER));
	m_cbxColor.AddString(str);
	m_cbxColor.SetItemData(OTHER_COLOR_ITEM_ID, m_dwColorOther);//8

	str="Context Color";
	m_cbxColor.AddString(str);
	m_cbxColor.SetItemData(CONTEXT_COLOR_ITEM_ID, m_contextColor);//9

	if(m_useContextColor){
		m_cbxColor.SetCurSel(CONTEXT_COLOR_ITEM_ID);
	}else{
		if(0<m_nColorId && m_nColorId-1<= MGColor::White){
			m_cbxColor.SetCurSel(m_nColorId - 1);
		}else{
			m_cbxColor.SetItemData(OTHER_COLOR_ITEM_ID, m_dwColorOther);
			m_cbxColor.SetCurSel(OTHER_COLOR_ITEM_ID);
		}
	}

	//if(m_useContextColor != BST_INDETERMINATE){
		GetDlgItem(IDC_CHECK_CONTEXT_COLOR)->ModifyStyle(BS_AUTO3STATE, BS_AUTOCHECKBOX);
	//}

	//if(m_line_width_context != BST_INDETERMINATE){
		GetDlgItem(IDC_LINE_ATTR)->ModifyStyle(BS_AUTO3STATE, BS_AUTOCHECKBOX);
	//}

	UpdateData(FALSE);

	OnBnClickedContextColor();
	OnBnClickedLineAttr();

	return TRUE;
}

void CGLColorLineAttribPage::OnOK(){
	UpdateData();
	m_dwColor = (DWORD)m_cbxColor.GetItemData(m_cbxColor.GetCurSel());
	CPropertyPage::OnOK();
}

void CGLColorLineAttribPage::OnBnClickedContextColor(){
	UpdateData();
	UINT cmd[] = {
		IDC_COMBO_COLOR,
		IDC_BUTTON_COLOR,
	};
	for(int i = 0; i < sizeof(cmd)/sizeof(UINT); i++){
		CWnd* pWnd = GetDlgItem(cmd[i]);
		pWnd->EnableWindow(!m_useContextColor);
	}
	if(m_useContextColor)
		m_cbxColor.SetCurSel(CONTEXT_COLOR_ITEM_ID);
}

void CGLColorLineAttribPage::OnBnClickedLineAttr(){
	UpdateData();
	
	//線幅-既定値を使用するにチェックされている場合エディットボックスをdisable
	GetDlgItem(IDC_EDIT_LINEWIDTH)->EnableWindow(m_line_width_context != BST_CHECKED);
	
	//線種-破線で描画するにチェックされている場合線種コントロールをenable
	// コンボボックス
	GetDlgItem(IDC_COMBO_STIPPLE_PRESET)->EnableWindow(!m_line_stipple_context && !m_bCustomStipple);
	// 線種をカスタマイズ depends on 破線で描画する
	GetDlgItem(IDC_CHECK_STIPPLE_CUSTOM)->EnableWindow(!m_line_stipple_context);
	// 係数・パターン depends on 線種をカスタマイズ
	GetDlgItem(IDC_EDIT_STIPPLE_FACTOR)->EnableWindow(!m_line_stipple_context && m_bCustomStipple);
	GetDlgItem(IDC_EDIT_STIPPLE_PATTERN)->EnableWindow(!m_line_stipple_context && m_bCustomStipple);
}
