void CReplaceTexDlg::BrowseTex(int iEdit)
{
	CString strTex;
	CWnd *pWnd = GetDlgItem(iEdit);

	pWnd->GetWindowText(strTex);

	CTextureBrowser *pBrowser = new CTextureBrowser(GetMainWnd());
	pBrowser->SetUsed(iEdit == IDC_FIND);
	pBrowser->SetInitialTexture(strTex);

	if (pBrowser->DoModal() == IDOK)
	{
		IEditorTexture *pTex = g_Textures.FindActiveTexture(pBrowser->m_cTextureWindow.szCurTexture);
		char szName[MAX_PATH];
		if (pTex != NULL)
		{
			pTex->GetShortName(szName);
		}
		else
		{
			szName[0] = '\0';
		}
		pWnd->SetWindowText(szName);
	}

	delete pBrowser;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : wParam - 
//			lParam - 
// Output : LRESULT
//-----------------------------------------------------------------------------
LRESULT CTextureBox::OnSelectString(WPARAM wParam, LPARAM lParam)
{
	LPCTSTR pszSelect = LPCTSTR(lParam);
	int iLen = strlen(pszSelect);

	int nCount = GetCount();
	IEditorTexture *pTex;

	for(int i = wParam + 1; i < nCount; i++)
	{
		pTex = (IEditorTexture *)GetItemDataPtr(i);
		if (pTex != NULL)
		{
			char szName[MAX_PATH];
			pTex->GetShortName(szName);
			if (!stricmp(szName, pszSelect))
			{
				SetCurSel(i);
				return i;
			}
		}
	}

	return LB_ERR;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CFaceEditMaterialPage::OnBrowse( void )
{
	// Set the material tool current.
	SetMaterialPageTool( MATERIALPAGETOOL_MATERIAL );

	CTextureBrowser *pBrowser = GetMainWnd()->pTextureBrowser;

	int iSel = m_TextureList.GetCurSel();

	if (iSel != LB_ERR)
	{
		IEditorTexture *pTex = (IEditorTexture *)m_TextureList.GetItemDataPtr(iSel);
		if (pTex != NULL)
		{
			char sz[128];
	
			pTex->GetShortName(sz);
			pBrowser->SetInitialTexture(sz);
		}
	}

	if (pBrowser->DoModal() == IDOK)
	{
		IEditorTexture *pTex = g_Textures.FindActiveTexture(pBrowser->m_cTextureWindow.szCurTexture);
		if (pTex != NULL)
		{
			int iCount = m_TextureList.GetCount();
			for (int i = 0; i < iCount; i++)
			{
				if (pTex == (IEditorTexture *)m_TextureList.GetItemDataPtr(i))
				{
					m_TextureList.SetCurSel(i);
					UpdateTexture();
					m_TextureList.AddMRU(pTex);
					break;
				}
			}
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : wParam - 
//			lParam - 
// Output : LRESULT
//-----------------------------------------------------------------------------
LRESULT CTextureBrowser::OnTexturewindowSelchange(WPARAM wParam, LPARAM lParam)
{
	IEditorTexture *pTex = g_Textures.FindActiveTexture(m_cTextureWindow.szCurTexture);
	CString str;
	char szName[MAX_PATH];

	if (pTex != NULL)
	{
		// create description of texture
		str.Format("%dx%d", pTex->GetWidth(), pTex->GetHeight());
		pTex->GetShortName(szName);
	}
	else
	{
		szName[0] = '\0';
	}

	m_cCurName.SetWindowText(szName);
	m_cCurDescription.SetWindowText(str);

	return(0);
}
//-----------------------------------------------------------------------------
// Purpose: Applies dialog data to the list of selected faces.
// Input  : *pOnlyFace - 
//			bAll - 
//-----------------------------------------------------------------------------
void CFaceEditMaterialPage::Apply( CMapFace *pOnlyFace, int flags )
{
	int			i;
	CString		str;
	float		fshiftX = NOT_INIT;
	float		fshiftY = NOT_INIT;
	float		fscaleX = NOT_INIT;
	float		fscaleY = NOT_INIT;
	float		frotate = NOT_INIT;
	int			material = NOT_INIT;
	int			nLightmapScale = NOT_INIT;
	IEditorTexture	*pTex = m_TexturePic.GetTexture();

	//
	// Get numeric data.
	//
	if (flags & FACE_APPLY_MAPPING)
	{
		TransferToFloat( &m_shiftX, fshiftX );
		TransferToFloat( &m_shiftY, fshiftY );
		TransferToFloat( &m_scaleX, fscaleX );
		TransferToFloat( &m_scaleY, fscaleY );
		TransferToFloat( &m_rotate, frotate );
	}

	if (flags & FACE_APPLY_LIGHTMAP_SCALE)
	{
		TransferToInteger( &m_cLightmapScale, nLightmapScale );
	}

	if ( !pOnlyFace )
	{
		GetHistory()->MarkUndoPosition( NULL, "Apply Face Attributes" );

		// make sure we apply everything in this case.
		flags |= FACE_APPLY_ALL;

		// Keep the solids that we are about to change.
		// In the pOnlyFace case we do the Keep before calling ClickFace. Why?
		CUtlVector<CMapSolid *> kept;
		CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
		for( i = 0; i < pSheet->GetFaceListCount(); i++ )
		{
			CMapSolid *pSolid = pSheet->GetFaceListDataSolid( i );
			if ( kept.Find( pSolid ) == -1 )
			{
				GetHistory()->Keep( pSolid );
				kept.AddToTail( pSolid );
			}
		}
	}
		
	//
	// Run thru stored faces & apply.
	//
	CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent();
	int faceCount = pSheet->GetFaceListCount();
	for( i = 0; i < faceCount || pOnlyFace; i++ )
	{
		CMapFace *pFace;
		if( pOnlyFace )
		{
			pFace = pOnlyFace;
		}
		else
		{
			pFace = pSheet->GetFaceListDataFace( i );
		}

		//
		// Get values for texture shift, scale, rotate, and material.
		//
		if ((flags & FACE_APPLY_MAPPING) && (!(flags & FACE_APPLY_ALIGN_EDGE)))
		{
			if ( fshiftX != NOT_INIT )
			{
				pFace->texture.UAxis[3] = fshiftX;
			}

			if ( fshiftY != NOT_INIT )
			{
				pFace->texture.VAxis[3] = fshiftY;
			}

			if ( fscaleX != NOT_INIT )
			{
				pFace->texture.scale[0] = fscaleX;
			}
			
			if ( fscaleY != NOT_INIT )
			{
				pFace->texture.scale[1] = fscaleY;
			}

			if ( frotate != NOT_INIT )
			{
				pFace->RotateTextureAxes( frotate - pFace->texture.rotate );
				pFace->texture.rotate = frotate;
			}
		}

		if (flags & FACE_APPLY_CONTENTS_DATA)
		{
			if ( material != NOT_INIT )
			{
				pFace->texture.material = material;
			}
		}

		if (flags & FACE_APPLY_LIGHTMAP_SCALE)
		{
			if (nLightmapScale != NOT_INIT)
			{
				pFace->texture.nLightmapScale = max( nLightmapScale, 1 );
			}
		}

		//
		// Update the texture and recalculate texture coordinates.
		//
		if ((flags & FACE_APPLY_MATERIAL) && (pTex != NULL))
		{
			char szCurrentTexName[MAX_PATH];
			char szNewTexName[MAX_PATH];

			pFace->GetTextureName( szCurrentTexName );
			pTex->GetShortName( szNewTexName );

			if( stricmp( szCurrentTexName, szNewTexName ) != 0 )
			{
				pFace->SetTexture( szNewTexName );
			}
		}

		//
		// Copy texture coordinate system.
		//
		if ((flags & FACE_APPLY_ALIGN_EDGE) && (faceCount >= 1))
		{
			CopyTCoordSystem( pSheet->GetFaceListDataFace( faceCount - 1 ), pFace );
		}

		//
		// Recalculate texture coordinates.
		//
		pFace->CalcTextureCoords();

		//
		// Update the face flags.
		//
		if (flags & FACE_APPLY_CONTENTS_DATA)
		{
			//
			// Copy the bits from this face into our variables.
			//
			m_FaceContents = pFace->texture.q2contents;
			m_FaceSurface = pFace->texture.q2surface;

			//
			// Update our variables based on the state of the checkboxes.
			//
			for( int nItem = 0; nItem < sizeof( FaceAttributes ) / sizeof( FaceAttributes[0] ); nItem++ )
			{
				CButton *pButton = ( CButton* )GetDlgItem( FaceAttributes[nItem].uControlID );
				if( pButton != NULL )
				{
					int nSet = pButton->GetCheck();

					if (nSet == 0)
					{
						*FaceAttributes[nItem].puAttribute &= ~FaceAttributes[nItem].uFlag;
					}
					else if (nSet == 1)
					{
						*FaceAttributes[nItem].puAttribute |= FaceAttributes[nItem].uFlag;
					}
				}	
			}

			//
			// Copy our variables back into this face.
			//
			pFace->texture.q2contents = m_FaceContents;
			pFace->texture.q2surface = m_FaceSurface;
		}

		if( pOnlyFace )
		{
			break;
		}
	}

	CMapDoc::GetActiveMapDoc()->SetModifiedFlag();
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : lpDrawItemStruct - 
//-----------------------------------------------------------------------------
void CTextureBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
//	if(!pGD)
//		return;

	CDC dc;
	dc.Attach(lpDrawItemStruct->hDC);
	dc.SaveDC();

	RECT& r = lpDrawItemStruct->rcItem;

	int iFontHeight = dc.GetTextExtent("J", 1).cy;

	if (lpDrawItemStruct->itemID != -1)
	{
		IEditorTexture *pTex = (IEditorTexture *)GetItemDataPtr(lpDrawItemStruct->itemID);
		dc.SetROP2(R2_COPYPEN);
		CPalette *pOldPalette = NULL;

		if (pTex != NULL)
		{
			pTex->Load();

			pOldPalette = dc.SelectPalette(pTex->HasPalette() ? pTex->GetPalette() : g_pGameConfig->Palette, FALSE);
			dc.RealizePalette();
		}

		COLORREF dwBackColor = RGB(255,255,255);
		COLORREF dwForeColor = RGB(0,0,0);

		if (lpDrawItemStruct->itemState & ODS_SELECTED)
		{
			dwBackColor = GetSysColor(COLOR_HIGHLIGHT);
			dwForeColor = GetSysColor(COLOR_HIGHLIGHTTEXT);
		}

		// draw background
		CBrush brush;
		brush.CreateSolidBrush(dwBackColor);
		dc.FillRect(&r, &brush);

		if (pTex == NULL)
		{
			// separator
			dc.SelectStockObject(BLACK_PEN);
			dc.MoveTo(r.left, r.top+5);
			dc.LineTo(r.right, r.top+5);
		}
		else
		{
			char szName[MAX_PATH];
			int iLen = pTex->GetShortName(szName);
			// when we get here, we are drawing a regular graphic. we
			//  check the size of the rectangle - if it's > 32 (just
			//	a nice number), we're drawing an item in the drop list.
			if ((r.bottom - r.top) > 32)
			{
				// draw graphic
				CRect r2(r);
				r2.InflateRect(-4, -4);
				r2.right = r2.left + 64;
				pTex->Draw(&dc, r2, 0, 0);

				// draw name
				dc.SetTextColor(dwForeColor);
				dc.SetBkMode(TRANSPARENT);
				dc.TextOut(r2.right + 4, r2.top + 4, szName, iLen);
				
				// draw size
				sprintf(szName, "%dx%d", pTex->GetWidth(), pTex->GetHeight());
				dc.TextOut(r2.right + 4, r2.top + 4 + iFontHeight, szName, strlen(szName));
			}
			// if it's < 32, we're drawing the item in the "closed"
			//	combo box, so just draw the name of the texture
			else
			{
				// just draw name - 
				dc.SetTextColor(dwForeColor);
				dc.SetBkMode(TRANSPARENT);
				dc.TextOut(r.left + 4, r.top + 2, szName, iLen);
			}
		}

		if (pOldPalette)
		{
			dc.SelectPalette(pOldPalette, FALSE);
		}
	}
	else if (lpDrawItemStruct->itemState & ODS_FOCUS)
	{
		dc.DrawFocusRect(&r);
	}

	dc.RestoreDC(-1);
	dc.Detach();
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTextureBox::LoadGraphicList(void)
{
	if (g_pGameConfig->GetTextureFormat() == tfNone)
	{
		return;
	}

	SetRedraw(FALSE);
	ResetContent();
	InitStorage(g_Textures.GetActiveTextureCount() + 32, sizeof(PVOID));

	//
	// Add the MRU textures to the list.
	//
	int nStrCount = 0;
	POSITION pos = g_Textures.MRUGetHeadPosition();
	while (pos != NULL)
	{
		IEditorTexture *pTex = g_Textures.MRUGetNext(pos, g_pGameConfig->GetTextureFormat());
		if (pTex != NULL)
		{
			char szStr[MAX_PATH];
			pTex->GetShortName(szStr);
			int err = AddString(szStr);
			SetItemDataPtr(nStrCount, (void *)pTex);
			nStrCount++;
		}	
	}

	//
	// Add the MRU seperator to the list, unless the MRU was empty.
	//
	if (nStrCount > 0)
	{
		AddString("");
		SetItemDataPtr(nStrCount, NULL);
		nStrCount++;
	}

	//
	// Add the rest of the textures to the list.
	//
	int nIndex = 0;
	IEditorTexture *pTex = g_Textures.EnumActiveTextures(&nIndex, g_pGameConfig->GetTextureFormat());
	while (pTex != NULL)
	{
		char szStr[MAX_PATH];
		pTex->GetShortName(szStr);
		int err = AddString(szStr);
		assert( (err != CB_ERR) && (err != CB_ERRSPACE) );
		SetItemDataPtr(nStrCount, (void *)pTex);
		nStrCount++;

		pTex = g_Textures.EnumActiveTextures(&nIndex, g_pGameConfig->GetTextureFormat());
	}

	//
	// Hack: Select one that doesn't start with '+', '!', or '*', and doesn't have "door" in it.
	//
	SetCurSel(0);

	int nSel = GetCount();
	for (int i = 0; i < nSel; i++)
	{
		IEditorTexture *pTexSearch = (IEditorTexture *)GetItemDataPtr(i);
		if (pTexSearch != NULL)
		{
			char szName[MAX_PATH];
			pTexSearch->GetShortName(szName);

			if ((szName[0] != 0) && (szName[0] != '*') && (szName[0] != '+') && (szName[0] != '!') && (strstr(szName, "door") == NULL))
			{
				// this one is ok
				SetCurSel(i);
				break;
			}
		}
	}

	SetRedraw(TRUE);
	Invalidate();
}
//-----------------------------------------------------------------------------
// Purpose: Rebuilds the MRU for this texture combo box.
//-----------------------------------------------------------------------------
void CTextureBox::RebuildMRU(void)
{
	SetRedraw(FALSE);

	int nCurSel = GetCurSel();

	//
	// Delete current MRUs from list.
	//
	int nItems = GetCount();
	int nDelimiterIndex = 0;
	while (nDelimiterIndex < nItems)
	{
		//
		// The first item with a NULL item data pointer is the MRU delimiter.
		//
		if (GetItemDataPtr(nDelimiterIndex) == NULL)
		{
			break;
		}

		nDelimiterIndex++;
	}

	//
	// If the MRU delimiter was found, delete everything before it.
	//
	if (nDelimiterIndex != nItems)
	{
		do
		{
			DeleteString(0);
		} while(nDelimiterIndex--);
	}

	//
	// Add each texture from the graphics MRU to this list's MRU.
	//
	int nCount = 0;
	POSITION pos = g_Textures.MRUGetHeadPosition();
	while (pos != NULL)
	{
		IEditorTexture *pTex = g_Textures.MRUGetNext(pos, g_pGameConfig->GetTextureFormat());
		if (pTex != NULL)
		{
			char szBuf[MAX_PATH];
			pTex->GetShortName(szBuf);

			int nIndex = InsertString(nCount, szBuf);
			SetItemDataPtr(nIndex, pTex);

			nCount++;
		}
	}

	//
	// Add the MRU seperator to the list, unless the MRU was empty.
	//
	if (nCount > 0)
	{
		int nIndex = InsertString(nCount, "");
		SetItemDataPtr(nIndex, NULL);
	}

	//
	// Restore the original selection.
	//
	SetCurSel(nCurSel);
	SetRedraw(TRUE);
	Invalidate();
}