ChEXPORT WrdDocumentProperties* WrdDocumentProperties::clone() const
{
    ChAutoPtr<WrdDOPTypography> pTypography((WrdDOPTypography*)m_pTypography->clone());
    ChAutoPtr<WrdDrawingObjectGrid> pGrid((WrdDrawingObjectGrid*)m_pGrid->clone());
    ChAutoPtr<WrdAutoSummaryInfo> pInfo((WrdAutoSummaryInfo*)m_pAutoSummary->clone());
    ChAutoPtr<WrdDateTime> pDate1((WrdDateTime*)m_pDateCreated->clone());
    ChAutoPtr<WrdDateTime> pDate2((WrdDateTime*)m_pDateRevised->clone());
    ChAutoPtr<WrdDateTime> pDate3((WrdDateTime*)m_pDateLastPrinted->clone());
    
    WrdDocumentProperties* pProps = ChNEW WrdDocumentProperties
    	((WrdDOPTypography*)pTypography.get(), (WrdDrawingObjectGrid*)pGrid.get(), 
        (WrdAutoSummaryInfo*)pInfo.get(), (WrdDateTime*)pDate1.get(), (WrdDateTime*)pDate2.get(), 
        (WrdDateTime*)pDate3.get());
    
    pDate3.giveUpOwnership();
    pDate2.giveUpOwnership();
    pDate1.giveUpOwnership();
    pInfo.giveUpOwnership();
    pGrid.giveUpOwnership();
    pTypography.giveUpOwnership();
	
	// Need to place this in an auto-pointer in case operator()= throws an exception
	ChAutoPtr<WrdDocumentProperties> pClone(pProps);
	*pClone = *this;
	return pClone.giveUpOwnership();
}
DWORD ToolGridVisibleEdit::GetSelectGrid(void)
{
	ui::Manager::_tagINPUTINFO *pInputInfo = ui::Manager::GetInstance()->GetInputInfoBuffer();
	//计算选中的格子
	static GameSelectRay cSelRay;
	RECT rc;
	EditWnd *pEditWnd = CommUI::GetInstance()->GetEditWnd();
	pEditWnd->GetWndRect(&rc);
	cSelRay.CalculateRay(&rc,pEditWnd->GetCamera(),pInputInfo->ptMouse);
	//显示格子
	EditMap *pMap = CommDB::GetInstance()->GetMap();
	VisibleSet *pSet = pMap->GetVisibleSet();
	DWORD *pVIArray = pSet->GetVisibleIndexArray();
	TerrainMesh *pMesh = CommDB::GetInstance()->GetTerrainMesh();
	TerrainMesh::_tagGrid *pGrid(NULL);
	TerrainMesh::_tagVertex *pVertexArray = pMesh->GetVertexList();
	D3DXVECTOR3 pos[4];
	DWORD dwSelGrid = 0xFFFFFFFF;
	float fDistance = 100000000.0f;
	float fTempDist;

	for(DWORD n = 0; n< pSet->GetVisibleIndexCount(); n++)
	{
		DWORD dwGridIndex = pVIArray[n];
		pGrid = pMesh->GetGrid(dwGridIndex);

		for(DWORD v = 0; v < 4; v++)
		{
			pos[v] = pVertexArray[pGrid->dwVertexIndex[v]].vPosition;
		}

	    if (cSelRay.IntersectTri(&pos[0],&pos[1],&pos[2],NULL,&fTempDist))
		{
			if (fTempDist < fDistance)
			{
				fDistance = fTempDist;
				dwSelGrid = dwGridIndex;
			}
		}
		else
			if (cSelRay.IntersectTri(&pos[0],&pos[2],&pos[3],NULL,&fTempDist))
			{	 
				if (fTempDist < fDistance)
				{
					fDistance = fTempDist;
					dwSelGrid = dwGridIndex;
				}

				
			}
	}
	return dwSelGrid;
}
void ToolGridVisibleEdit::DrawBrush(void)
{
	if (m_dwCurSelGrid == 0xFFFFFFFF) 
		return;

	render::Interface *pInterface = render::Interface::GetInstance();
	render::Interface::Layer3D *pLayer3D = render::Interface::GetInstance()->GetLayer3D();

	EditMap *pMap = CommDB::GetInstance()->GetMap();
	DWORD dwMapWidth = pMap->GetWidth();
	DWORD dwMapDepth = pMap->GetDepth();
	int iCenterX = m_dwCurSelGrid % dwMapWidth;
	int iCenterZ = m_dwCurSelGrid / dwMapWidth;

	TerrainMesh *pMesh = CommDB::GetInstance()->GetTerrainMesh();
	TerrainMesh::_tagGrid *pGrid(NULL);
	TerrainMesh::_tagVertex *pVertexArray = pMesh->GetVertexList();
	D3DXVECTOR3 pos[4];


	for(int j = - m_iBrushSize; j < m_iBrushSize + 1; j++)
	{
		for(int i = - m_iBrushSize; i < m_iBrushSize + 1;i++)
		{
			int iX = iCenterX + i;
			int iZ = iCenterZ + j;

			if (!(iX < 0 || iX >= (int)dwMapWidth || iZ < 0 || iZ >= (int)dwMapDepth))
			{
				//在地图内
				//显示格子
				DWORD dwGridIndex = iX + iZ * dwMapWidth;
				pGrid = pMesh->GetGrid(dwGridIndex);

				for(DWORD v = 0; v < 4; v++)
				{
					pos[v] = pVertexArray[pGrid->dwVertexIndex[v]].vPosition;
					pos[v].y += 0.02f;
				}

				//pLayer3D->_DEBUG_DrawTriangle(&pos[0],&pos[1],&pos[2],dwMtlColor[iMtlSelIndex]);
				//pLayer3D->_DEBUG_DrawTriangle(&pos[0],&pos[2],&pos[3],dwMtlColor[iMtlSelIndex]);
				pLayer3D->_DEBUG_DrawTriangle(&pos[0],&pos[1],&pos[2],0x8080ff80);
				pLayer3D->_DEBUG_DrawTriangle(&pos[0],&pos[2],&pos[3],0x8080ff80);
				pLayer3D->_DEBUG_DrawWireQuad(&pos[0],&pos[1],&pos[2],&pos[3],0xff00ff00);
			}
		}
	}
}
    FdmHestonVarianceMesher::FdmHestonVarianceMesher(
        Size size,
        const boost::shared_ptr<HestonProcess> & process,
        Time maturity, Size tAvgSteps, Real epsilon)
        : Fdm1dMesher(size) {

        std::vector<Real> vGrid(size, 0.0), pGrid(size, 0.0);
        const Real df  = 4*process->theta()*process->kappa()/
                            square<Real>()(process->sigma());
        try {
            std::multiset<std::pair<Real, Real> > grid;
            
            for (Size l=1; l<=tAvgSteps; ++l) {
                const Real t = (maturity*l)/tAvgSteps;
                const Real ncp = 4*process->kappa()*std::exp(-process->kappa()*t)
                    /(square<Real>()(process->sigma())
                    *(1-std::exp(-process->kappa()*t)))*process->v0();
                const Real k = square<Real>()(process->sigma())
                    *(1-std::exp(-process->kappa()*t))/(4*process->kappa());

                const Real qMin = 0.0; // v_min = 0.0;
                const Real qMax = std::max(process->v0(),
                    k*InverseNonCentralChiSquareDistribution(
                                            df, ncp, 1000,  1e-8)(1-epsilon));

                const Real minVStep=(qMax-qMin)/(50*size);
                Real ps,p = 0.0;

                Real vTmp = qMin;
                grid.insert(std::pair<Real, Real>(qMin, epsilon));
                
                for (Size i=1; i < size; ++i) {
                    ps = (1 - epsilon - p)/(size-i);
                    p += ps;
                    const Real tmp = k*InverseNonCentralChiSquareDistribution(
                        df, ncp, 1000, 1e-8)(p);

                    const Real vx = std::max(vTmp+minVStep, tmp);
                    p = NonCentralChiSquareDistribution(df, ncp)(vx/k);
                    vTmp=vx;
                    grid.insert(std::pair<Real, Real>(vx, p));
                }
            }
            QL_REQUIRE(grid.size() == size*tAvgSteps, 
                       "something wrong with the grid size");
            
            std::vector<std::pair<Real, Real> > tp(grid.begin(), grid.end());

            for (Size i=0; i < size; ++i) {
                const Size b = (i*tp.size())/size;
                const Size e = ((i+1)*tp.size())/size;
                for (Size j=b; j < e; ++j) {
                    vGrid[i]+=tp[j].first/(e-b);
                    pGrid[i]+=tp[j].second/(e-b);
                }
            }
        } 
        catch (const Error&) {
            // use default mesh
            const Real vol = process->sigma()*
                std::sqrt(process->theta()/(2*process->kappa()));

            const Real mean = process->theta();
            const Real upperBound = std::max(process->v0()+4*vol, mean+4*vol);
            const Real lowerBound
                = std::max(0.0, std::min(process->v0()-4*vol, mean-4*vol));

            for (Size i=0; i < size; ++i) {
                pGrid[i] = i/(size-1.0);
                vGrid[i] = lowerBound + i*(upperBound-lowerBound)/(size-1.0);
            }
        }

        Real skewHint = ((process->kappa() != 0.0) 
                ? std::max(1.0, process->sigma()/process->kappa()) : 1.0);

        std::sort(pGrid.begin(), pGrid.end());
        volaEstimate_ = GaussLobattoIntegral(100000, 1e-4)(
            boost::function1<Real, Real>(
                compose(std::ptr_fun<Real, Real>(std::sqrt),
                        LinearInterpolation(pGrid.begin(), pGrid.end(),
                        vGrid.begin()))),
            pGrid.front(), pGrid.back())*std::pow(skewHint, 1.5);
        
        const Real v0 = process->v0();
        for (Size i=1; i<vGrid.size(); ++i) {
            if (vGrid[i-1] <= v0 && vGrid[i] >= v0) {
                if (std::fabs(vGrid[i-1] - v0) < std::fabs(vGrid[i] - v0))
                    vGrid[i-1] = v0;
                else
                    vGrid[i] = v0;
            }
        }

        std::copy(vGrid.begin(), vGrid.end(), locations_.begin());

        for (Size i=0; i < size-1; ++i) {
            dminus_[i+1] = dplus_[i] = vGrid[i+1] - vGrid[i];
        }
        dplus_.back() = dminus_.front() = Null<Real>();
    }
void ToolDoorEdit::DrawSelected(void)
{
	DWORD dwSelCount = (DWORD)m_vSelGridIndexArray.size();
	if (!dwSelCount) return;
	render::Interface::Layer3D *pLayer3D = render::Interface::GetInstance()->GetLayer3D();
	render::Interface::Layer2D *pLayer2D = render::Interface::GetInstance()->GetLayer2D();

	D3DVIEWPORT9 tViewport;
	render::Interface::GetInstance()->GetDevice()->GetViewport(&tViewport);
	D3DXMATRIX matWrold;
	D3DXMatrixIdentity(&matWrold);

	//循环可见格子
	EditMap *pMap = CommDB::GetInstance()->GetMap();
	Grid	*pMapGrid(NULL);
	TerrainMesh *pMesh = CommDB::GetInstance()->GetTerrainMesh();
	TerrainMesh::_tagGrid *pGrid(NULL);
	TerrainMesh::_tagVertex *pVertexArray = pMesh->GetVertexList();
	
	static D3DXVECTOR3 pos[4],vCenter;;
	
	WndDoorEdit *pWndDoorEdit = CommUI::GetInstance()->GetEditWnd()->GetWndDoorEdit();
	render::Camera *pCamera = CommUI::GetInstance()->GetEditWnd()->GetCamera();
	for(DWORD n = 0;n < dwSelCount; n++)
	{
		DWORD dwGridIndex = m_vSelGridIndexArray[n];
		pMapGrid = pMap->GetGrid(dwGridIndex);
		pMap->GetGridPosition(dwGridIndex,pos,&vCenter);
		pLayer3D->_DEBUG_DrawTriangle(&pos[0],&pos[1],&pos[2],0xa077ff77);
		pLayer3D->_DEBUG_DrawTriangle(&pos[0],&pos[2],&pos[3],0xa077ff77);
		//画名字
		int iDoorIndex = pMapGrid->GetDoorIndex() - 1;
		if (iDoorIndex >= 0)
		{
			D3DXVec3Project(&vCenter,&vCenter,&tViewport,pCamera->GetProjectionMatrix(),
				pCamera->GetViewMatrix(),&matWrold);
			tagDoor *pDoor = pWndDoorEdit->GetDoor(iDoorIndex);
			int iTexLen = lstrlen(pDoor->szName);

			int iTextWidth = pLayer2D->CalcTextWidth(pDoor->szName,iTexLen);
			int iTextHeight= pLayer2D->GetFontSize();

			int iWidth = iTextWidth + 16;	

			int iStartX = (int)vCenter.x - iWidth / 2;
			int iStartY = (int)vCenter.y - iTextHeight/2;

			pLayer2D->DrawSolidQuad(iStartX - 2,iStartY ,iTextWidth + 8,iTextHeight + 2 ,0x80bbc5ff);

			ui::Wnd::SetUIRendState();
			pLayer2D->OutPutText(iStartX + 1,iStartY + 1,pDoor->szName,iTexLen,FWC_BLACK);
			pLayer2D->OutPutText(iStartX - 1,iStartY - 1,pDoor->szName,iTexLen,FWC_BLACK);
			pLayer2D->OutPutText(iStartX + 1,iStartY - 1,pDoor->szName,iTexLen,FWC_BLACK);
			pLayer2D->OutPutText(iStartX - 1,iStartY + 1,pDoor->szName,iTexLen,FWC_BLACK);
			pLayer2D->OutPutText(iStartX + 1,iStartY,pDoor->szName,iTexLen,FWC_BLACK);
			pLayer2D->OutPutText(iStartX - 1,iStartY,pDoor->szName,iTexLen,FWC_BLACK);
			pLayer2D->OutPutText(iStartX,iStartY + 1,pDoor->szName,iTexLen,FWC_BLACK);
			pLayer2D->OutPutText(iStartX,iStartY - 1,pDoor->szName,iTexLen,FWC_BLACK);  
			pLayer2D->OutPutText(iStartX,iStartY,pDoor->szName,iTexLen,0xFF44FF55);  

		}
	}
}
void ToolDoorEdit::Render()
{
	ui::Manager::_tagINPUTINFO *pInputInfo = ui::Manager::GetInstance()->GetInputInfoBuffer();
	render::Interface *pInterface = render::Interface::GetInstance();
	render::Interface::Layer2D   *pLayer2D   = pInterface->GetLayer2D();
	render::Interface::Layer3D   *pLayer3D   = pInterface->GetLayer3D();

	EditWnd *pEditWnd = CommUI::GetInstance()->GetEditWnd();

	WndDoorEdit *pWndDoorEdit= pEditWnd->GetWndDoorEdit();
	DWORD dwSelIndex = pWndDoorEdit->GetCurDoorIndex();

	switch(m_eEditStatus)
	{
	case DEST_SELECT:
		if (m_bDrag)
		{
			//画拖动线
			pLayer2D->DrawWireQuadRect(m_ptDragStart.x,m_ptDragStart.y,pInputInfo->ptMouse.x,pInputInfo->ptMouse.y,0xffffffff);
		}
		DrawSelected();
		break;
	case DEST_PALACE:
		{
			D3DXMATRIX matTRS;

			//显示被点亮的格子
			static GameSelectRay cSelRay;
			RECT rc;
			pEditWnd->GetWndRect(&rc);
			cSelRay.CalculateRay(&rc,pEditWnd->GetCamera(),pInputInfo->ptMouse);
			//显示格子
			
			EditMap *pMap = CommDB::GetInstance()->GetMap();
			if (pMap)
			{
				VisibleSet *pSet = pMap->GetVisibleSet();
				DWORD *pVIArray = pSet->GetVisibleIndexArray();
				TerrainMesh *pMesh = CommDB::GetInstance()->GetTerrainMesh();
				TerrainMesh::_tagGrid *pGrid(NULL);
				TerrainMesh::_tagVertex *pVertexArray = pMesh->GetVertexList();
				D3DXVECTOR3 pos[4];
				D3DXVECTOR3 vCenter;

				for(DWORD n = 0; n< pSet->GetVisibleIndexCount(); n++)
				{
					DWORD dwGridIndex = pVIArray[n];

					pGrid = pMesh->GetGrid(dwGridIndex);

					for(DWORD v= 0; v < 4; v++)
					{
						pos[v] = pVertexArray[pGrid->dwVertexIndex[v]].vPosition;
					}

					vCenter = (pos[0] + pos[1] + pos[2] + pos[3]) / 4.0f;
					if (cSelRay.IntersectTri(&pos[0],&pos[1],&pos[2],NULL,NULL) || cSelRay.IntersectTri(&pos[0],&pos[2],&pos[3],NULL,NULL))
					{
						//这个格子被选中
						pLayer3D->_DEBUG_DrawWireQuad(&pos[0],&pos[1],&pos[2],&pos[3],0xffff0000);

						D3DXMatrixTranslation(&matTRS,vCenter.x,vCenter.y,vCenter.z);
						
						RnderDoorModel(&matTRS);	

						break;
					}
				}
			}
		}
		break;
	}

	_ShowStatus();
}
void ToolGridVisibleEdit::PaintBrush(BOOL  bVisible)
{
	if (m_dwCurSelGrid == 0xFFFFFFFF)
		return;       
	
	EditMap *pMap = CommDB::GetInstance()->GetMap();
	DWORD dwMapWidth = pMap->GetWidth();
	DWORD dwMapDepth = pMap->GetDepth();
	int iCenterX = m_dwCurSelGrid % dwMapWidth;
	int iCenterZ = m_dwCurSelGrid / dwMapWidth;

	TerrainMesh *pMesh = CommDB::GetInstance()->GetTerrainMesh();
	TerrainMesh::_tagGrid *pGrid(NULL);
	TerrainMesh::_tagVertex *pVertexArray = pMesh->GetVertexList();
	D3DXVECTOR3 pos[4];

	BOOL bAllLike = TRUE;

	for(int j = - m_iBrushSize; j < m_iBrushSize + 1; j++)
	{
		for(int i = - m_iBrushSize; i < m_iBrushSize + 1;i++)
		{
			int iX = iCenterX + i;
			int iZ = iCenterZ + j;

			if (!(iX < 0 || iX >= (int)dwMapWidth || iZ < 0 || iZ >= (int)dwMapDepth))
			{
				//在地图内
				//显示格子
				DWORD dwGridIndex = iX + iZ * dwMapWidth;
				//检查是否全部相同
				if (pMap->GetGrid(dwGridIndex)->GetVisible() != bVisible)
				{
					bAllLike = FALSE;
					break;
				}
			}
		}
	}
	if (!bAllLike)//有不同,则涂
	{
		CmdMapFillGridVisible *pCmd = new CmdMapFillGridVisible;
		pCmd->SetVisible(bVisible);
		for(int j = - m_iBrushSize; j < m_iBrushSize + 1; j++)
		{
			for(int i = - m_iBrushSize; i < m_iBrushSize + 1;i++)
			{
				int iX = iCenterX + i;
				int iZ = iCenterZ + j;

				if (!(iX < 0 || iX >= (int)dwMapWidth || iZ < 0 || iZ >= (int)dwMapDepth))
				{
					//在地图内
					//显示格子
					DWORD dwGridIndex = iX + iZ * dwMapWidth;
					pCmd->AddGridIndex(dwGridIndex);					
				}
			}
		}
		CmdMgr::GetInstance()->Do(pCmd);
	}
}