void CBaseEventPropertiesDialog::PopulateTagList( CEventParams *params )
{
	CChoreoScene *scene = params->m_pScene;
	if ( !scene )
		return;

	HWND control = GetControl( IDC_TAGS );
	if ( control )
	{
		SendMessage( control, CB_RESETCONTENT, 0, 0 ); 
		SendMessage( control, WM_SETTEXT , 0, (LPARAM)va( "\"%s\" \"%s\"", params->m_szTagName, params->m_szTagWav ) );

		for ( int i = 0; i < scene->GetNumActors(); i++ )
		{
			CChoreoActor *a = scene->GetActor( i );
			if ( !a )
				continue;

			for ( int j = 0; j < a->GetNumChannels(); j++ )
			{
				CChoreoChannel *c = a->GetChannel( j );
				if ( !c )
					continue;

				for ( int k = 0 ; k < c->GetNumEvents(); k++ )
				{
					CChoreoEvent *e = c->GetEvent( k );
					if ( !e )
						continue;

					if ( e->GetNumRelativeTags() <= 0 )
						continue;

					// add each tag to combo box
					for ( int t = 0; t < e->GetNumRelativeTags(); t++ )
					{
						CEventRelativeTag *tag = e->GetRelativeTag( t );
						if ( !tag )
							continue;

						SendMessage( control, CB_ADDSTRING, 0, (LPARAM)va( "\"%s\" \"%s\"", tag->GetName(), e->GetParameters() ) ); 
					}
				}
			}
		}
	}
}
	virtual int handleEvent( mxEvent *event )
	{
		int iret = 0;
		switch ( event->event )
		{
		default:
			break;
		case mxEvent::Action:
			{
				iret = 1;
				switch ( event->action )
				{
				default:
					iret = 0;
					break;
				case IDC_MODELTAB_SHOWALL:
				case IDC_MODELTAB_HIDEALL:
					{
						bool show = ( event->action == IDC_MODELTAB_SHOWALL ) ? true : false;
						int c = models->Count();
						for ( int i = 0; i < c ; i++ )
						{
							models->ShowModelIn3DView( i, show );
						}
					}
					break;
				case IDC_MODELTAB_LOAD:
					{
						const char *ptr = mxGetOpenFileName(
							this, 
							FacePoser_MakeWindowsSlashes( va( "%s/models/", GetGameDirectory() ) ), 
							"*.mdl" );

						if (ptr)
						{
							g_MDLViewer->LoadModelFile( ptr );
						}
					}
					break;
				case IDC_MODELTAB_CLOSE:
					{
						int idx = getSelectedIndex();
						if ( idx >= 0 )
						{
							models->FreeModel( idx );
						}
					}
					break;
				case IDC_MODELTAB_CLOSEALL:
					{
						models->CloseAllModels();
					}
					break;
				case IDC_MODELTAB_CENTERONFACE:
					{
						g_pControlPanel->CenterOnFace();
					}
					break;
				case IDC_MODELTAB_TOGGLE3DVIEW:
					{
						int idx = getSelectedIndex();
						if ( idx >= 0 )
						{
							bool visible = models->IsModelShownIn3DView( idx );
							models->ShowModelIn3DView( idx, !visible );
						}
					}
					break;
				case IDC_MODELTAB_ASSOCIATEACTOR:
					{
						int idx = getSelectedIndex();
						if ( idx >= 0 )
						{
							char const *modelname = models->GetModelFileName( idx );

							CChoreoScene *scene = g_pChoreoView->GetScene();
							if ( scene )
							{
								CChoiceParams params;
								strcpy( params.m_szDialogTitle, "Associate Actor" );

								params.m_bPositionDialog = false;
								params.m_nLeft = 0;
								params.m_nTop = 0;
								strcpy( params.m_szPrompt, "Choose actor:" );

								params.m_Choices.RemoveAll();

								params.m_nSelected = -1;
								int oldsel = -1;

								int c = scene->GetNumActors();
								ChoiceText text;
								for ( int i = 0; i < c; i++ )
								{
									CChoreoActor *a = scene->GetActor( i );
									Assert( a );

									
									strcpy( text.choice, a->GetName() );

									if ( !stricmp( a->GetFacePoserModelName(), modelname ) )
									{
										params.m_nSelected = i;
										oldsel = -1;
									}

									params.m_Choices.AddToTail( text );
								}
		
								if ( ChoiceProperties( &params ) && 
									params.m_nSelected != oldsel )
								{
									
									// Chose something new...
									CChoreoActor *a = scene->GetActor( params.m_nSelected );
									
									g_pChoreoView->AssociateModelToActor( a, idx );
								}
							}
						}

					}
				}
			}
			break;
		}
		if ( iret )
			return iret;
		return BaseClass::handleEvent( event );
	}
	virtual void ShowRightClickMenu( int mx, int my )
	{
		mxPopupMenu *pop = new mxPopupMenu();
		Assert( pop );

		char const *current = "";
		char const *filename = "";
		int idx = getSelectedIndex();
		if ( idx >= 0 )
		{
			current = models->GetModelName( idx );
			filename = models->GetModelFileName( idx );
		}

		if ( models->Count() < MAX_FP_MODELS )
		{
			pop->add( "Load Model...", IDC_MODELTAB_LOAD );
		}
		if ( idx >= 0 )
		{
			pop->add( va( "Close '%s'", current ), IDC_MODELTAB_CLOSE );
		}
		if ( models->Count() > 0 )
		{
			pop->add( "Close All", IDC_MODELTAB_CLOSEALL );
		}
		if ( idx >= 0 )
		{
			pop->addSeparator();
			pop->add( va( "Center %s's face", current ), IDC_MODELTAB_CENTERONFACE );

			CChoreoScene *scene = g_pChoreoView->GetScene();
			if ( scene )
			{
				// See if there is already an actor with this model associated
				int c = scene->GetNumActors();
				bool hasassoc = false;
				for ( int i = 0; i < c; i++ )
				{
					CChoreoActor *a = scene->GetActor( i );
					Assert( a );
				
					if ( stricmp( a->GetFacePoserModelName(), filename ) )
						continue;
					hasassoc = true;
					break;
				}

				if ( hasassoc )
				{
					pop->add( va( "Change associated actor for %s", current ), IDC_MODELTAB_ASSOCIATEACTOR );
				}
				else
				{
					pop->add( va( "Associate actor to %s", current ), IDC_MODELTAB_ASSOCIATEACTOR );
				}
			}

			pop->addSeparator();

			bool visible = models->IsModelShownIn3DView( idx );
			if ( visible )
			{
				pop->add( va( "Remove %s from 3D View", current ), IDC_MODELTAB_TOGGLE3DVIEW );
			}
			else
			{
				pop->add( va( "Show %s in 3D View", current ), IDC_MODELTAB_TOGGLE3DVIEW );
			}
		}
		if ( models->Count() > 0 )
		{
			pop->addSeparator();
			pop->add( "Show All", IDC_MODELTAB_SHOWALL );
			pop->add( "Hide All", IDC_MODELTAB_HIDEALL );
		}

		// Convert click position
		POINT pt;
		pt.x = mx;
		pt.y = my;

		// Convert coordinate space
		pop->popup( this, pt.x, pt.y );
	}
void CBaseEventPropertiesDialog::PopulateNamedActorList( HWND wnd, CEventParams *params )
{
	int i;

	char const *mapname = NULL;
	if ( params->m_pScene )
	{
		mapname = params->m_pScene->GetMapname();
	}

	CUtlRBTree< char const *, int >		m_SortedNames( 0, 0, NameLessFunc );

	if ( mapname )
	{
		g_MapEntities.CheckUpdateMap( mapname );

		for ( i = 0; i < g_MapEntities.Count(); i++ )
		{
			char const *name = g_MapEntities.GetName( i );
			if ( name && name[ 0 ] )
			{
				m_SortedNames.Insert( name );
			}
		}
	}

	for ( i = 0 ; i < params->m_pScene->GetNumActors() ; i++ )
	{
		CChoreoActor *actor = params->m_pScene->GetActor( i );
		if ( actor && actor->GetName() && actor->GetName()[0] )
		{
			if ( m_SortedNames.Find( actor->GetName() ) == m_SortedNames.InvalidIndex() )
			{
				m_SortedNames.Insert( actor->GetName() );
			}
		}
	}

	i = m_SortedNames.FirstInorder();
	while ( i != m_SortedNames.InvalidIndex() )
	{
		char const *name = m_SortedNames[ i ];
		if ( name && name[ 0 ] )
		{
			SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)name ); 
		}

		i = m_SortedNames.NextInorder( i );
	}

	/*
	// Note have to do this here, after posting data to the control, since we are storing a raw string pointer in m_SortedNames!!!
	if ( allActors )
	{
		allActors->deleteThis();
	}
	*/

	// These events can also be directed at another player or named target, too
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!player" );
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!enemy" );
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!self" );
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!friend" );
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!speechtarget" );
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target1" );
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target2" );
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target3" );
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target4" );
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target5" );
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target6" );
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target7" );
	SendMessage( wnd, CB_ADDSTRING, 0, (LPARAM)"!target8" );
}
void CheckForOverlappingFlexTracks( CChoreoScene *scene )
{
    for ( int a = 0; a < scene->GetNumActors(); ++a )
    {
        CChoreoActor *actor = scene->GetActor( a );

        CUtlRBTree< CChoreoEvent * >  actorFlexEvents( 0, 0, ChoreEventStartTimeLessFunc );

        for ( int c = 0; c < actor->GetNumChannels(); ++c )
        {
            CChoreoChannel *channel = actor->GetChannel( c );

            for ( int e = 0 ; e < channel->GetNumEvents(); ++e )
            {
                CChoreoEvent *event = channel->GetEvent( e );

                if ( event->GetType() != CChoreoEvent::FLEXANIMATION )
                    continue;

                actorFlexEvents.Insert( event );
            }
        }

        CUtlVector< CUtlLinkedList< CChoreoEvent*, int > >	rows;

        bool done = false;
        int i;
        // Now check for overlaps
        for ( i = actorFlexEvents.FirstInorder(); i != actorFlexEvents.InvalidIndex() && !done; i = actorFlexEvents.NextInorder( i ) )
        {
            CChoreoEvent *e = actorFlexEvents[ i ];
            if ( !rows.Count() )
            {
                rows.AddToTail();

                CUtlLinkedList< CChoreoEvent*, int >& list = rows[ 0 ];
                list.AddToHead( e );
                continue;
            }

            // Does it come totally after what's in rows[0]?
            int rowCount = rows.Count();
            bool addrow = true;

            for ( int j = 0; j < rowCount; j++ )
            {
                CUtlLinkedList< CChoreoEvent*, int >& list = rows[ j ];

                char offender[ 256 ];
                if ( !EventCollidesWithRows( list, e, offender, sizeof( offender ) ) )
                {
                    // Update row event list
                    list.AddToHead( e );
                    addrow = false;
                    break;
                }
                else
                {
                    Msg( "[%s] has overlapping events for actor [%s] [%s] [flex: %s]\n",
                         scene->GetFilename(), actor->GetName(), e->GetName(), offender );
                    done = true;
                }
            }

            if ( addrow )
            {
                // Add a new row
                int idx = rows.AddToTail();
                CUtlLinkedList< CChoreoEvent *, int >& list = rows[ idx ];
                list.AddToHead( e );
            }
        }

        // Assert( rows.Count() <= 1 );
    }
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : hwndDlg - 
//			uMsg - 
//			wParam - 
//			lParam - 
// Output : static BOOL CALLBACK ChannelPropertiesDialogProc
//-----------------------------------------------------------------------------
static BOOL CALLBACK ChannelPropertiesDialogProc ( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) 
{
	switch(uMsg)
	{
    case WM_INITDIALOG:
		// Insert code here to put the string (to find and replace with)
		// into the edit controls.
		// ...
		{
			g_Params.PositionSelf( hwndDlg );

			SetDlgItemText( hwndDlg, IDC_CHANNELNAME, g_Params.m_szName );

			HWND control = GetDlgItem( hwndDlg, IDC_ACTORCHOICE );

			if ( !g_Params.m_bShowActors )
			{
				// Hide the combo box
				if ( control )
				{
					ShowWindow( control, SW_HIDE );
				}
				control = GetDlgItem( hwndDlg, IDC_STATIC_ACTOR );
				if ( control )
				{
					ShowWindow( control, SW_HIDE );
				}
			}
			else
			{
				SendMessage( control, CB_RESETCONTENT, 0, 0 ); 

				if ( g_Params.m_pScene )
				{
					for ( int i = 0 ; i < g_Params.m_pScene->GetNumActors() ; i++ )
					{
						CChoreoActor *actor = g_Params.m_pScene->GetActor( i );
						if ( actor )
						{
							// add text to combo box
							SendMessage( control, CB_ADDSTRING, 0, (LPARAM)actor->GetName() ); 
						}
					}
				}
				
				SendMessage( control, CB_SETCURSEL, (WPARAM)0, (LPARAM)0 );
			}

			SetWindowText( hwndDlg, g_Params.m_szDialogTitle );

			SetFocus( GetDlgItem( hwndDlg, IDC_CHANNELNAME ) );
		}
		return FALSE;  
		
    case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case IDOK:
			g_Params.m_szName[ 0 ] = 0;
			GetDlgItemText( hwndDlg, IDC_CHANNELNAME, g_Params.m_szName, 256 );

			if ( g_Params.m_bShowActors )
			{
				HWND control = GetDlgItem( hwndDlg, IDC_ACTORCHOICE );
				if ( control )
				{
					SendMessage( control, WM_GETTEXT, (WPARAM)sizeof( g_Params.m_szSelectedActor ), (LPARAM)g_Params.m_szSelectedActor );
				}
			}

			EndDialog( hwndDlg, 1 );
			break;
        case IDCANCEL:
			EndDialog( hwndDlg, 0 );
			break;
		}
		return TRUE;
	}
	return FALSE;
}