/*----------------------------------------------------------------------------
miniAudicle
GUI to chuck audio programming environment

Copyright (c) 2005 Spencer Salazar.  All rights reserved.
http://chuck.cs.princeton.edu/
http://soundlab.cs.princeton.edu/

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
U.S.A.
-----------------------------------------------------------------------------*/

//-----------------------------------------------------------------------------
// file: mAMenuBar.cpp
// desc: Creates and manages the miniAudicle menubar
//
// author: Spencer Salazar (ssalazar@cs.princeton.edu)
// date: Summer 2006
//-----------------------------------------------------------------------------

#include "chuck_def.h"

#include "mAMenuBar.h"
#include "mAParentFrame.h"
#include "mAEvents.h"

mAMenuBar::mAMenuBar() : wxMenuBar()
{
	vm_on = FALSE;

	wxMenu * file_menu = new wxMenu;
	wxMenu * edit_menu = new wxMenu;
	chuck_menu = new wxMenu;
	log_menu = new wxMenu;
	window_menu = new wxMenu;
	wxMenu * help_menu = new wxMenu;
	file_history_menu = new wxMenu;
	
	file_menu->Append( wxID_NEW, _T( "&New\tCtrl+N" ) );
	file_menu->Append( wxID_OPEN, _T( "&Open...\tCtrl+O" ) );
	file_menu->Append( wxID_CLOSE, _T( "&Close\tCtrl+W" ) );

	file_menu->AppendSeparator();
	file_menu->Append( wxID_SAVE, _T( "&Save\tCtrl+S" ) );
	file_menu->Append( wxID_SAVEAS, _T( "Save &As...\tShift+Ctrl+S" ) );

	//file_menu->AppendSeparator();
	//file_menu->Append( wxID_PREVIEW, _T( "Print Pre&view" ) );
	//file_menu->Append( wxID_PRINT, _T( "&Print...\tCtrl+P" ) );

	file_menu->AppendSeparator();
	file_menu->Append( wxID_ANY, _T( "Recent &Files..." ), 
		file_history_menu );

	file_menu->AppendSeparator();
	file_menu->Append( wxID_EXIT, _T( "E&xit\tAlt+X" ) );

	edit_menu->Append( mAID_UNDO, _T( "&Undo\tCtrl+Z" ) );
	edit_menu->Append( mAID_REDO, _T( "&Redo\tCtrl+Y" ) );
	edit_menu->AppendSeparator();
	edit_menu->Append( mAID_CUT, _T( "Cu&t\tCtrl+X" ) );
	edit_menu->Append( mAID_COPY, _T( "&Copy\tCtrl+C" ) );
	edit_menu->Append( mAID_PASTE, _T( "&Paste\tCtrl+V" ) );
//	edit_menu->Append( mAID_DELETE, _T( "&Delete\tDel" ) );
	edit_menu->AppendSeparator();
	edit_menu->Append( mAID_SELECTALL, _T( "Select A&ll\tCtrl+A" ) );
	edit_menu->AppendSeparator();
	edit_menu->Append( mAID_PREFERENCES, _T( "Pre&ferences...\tAlt+," ) );

	chuck_menu->Append( mAID_ADD, _T( "&Add Shred\tAlt++" ) );
	chuck_menu->Append( mAID_REPLACE, _T( "Re&place Shred\tAlt+=" ) );
	chuck_menu->Append( mAID_REMOVE, _T( "&Remove Shred\tAlt+-" ) );
	chuck_menu->AppendSeparator();
	chuck_menu->Append( mAID_REMOVELAST, _T( "Remove &Last Shred" ) );
	chuck_menu->Append( mAID_REMOVEALL, _T( "Remove All Shreds\tAlt+DEL" ) );
	chuck_menu->AppendSeparator();
	chuck_menu->Append( mAID_ABORT_CURRENT_SHRED, _T( "Abort Currently Running Shred\tAlt+K" ) );
	chuck_menu->AppendSeparator();
	chuck_menu->Append( mAID_TOGGLE_VM, _T( "&Start Virtual Machine\tAlt+." ) );
	
	log_menu->AppendCheckItem( mAID_LOG + 0, _T( "&None" ) );
	log_menu->AppendCheckItem( mAID_LOG + 1, _T( "&Core" ) );
	log_menu->AppendCheckItem( mAID_LOG + 2, _T( "&System" ) );
	log_menu->AppendCheckItem( mAID_LOG + 3, _T( "S&evere" ) );
	log_menu->AppendCheckItem( mAID_LOG + 4, _T( "&Warning" ) );
	log_menu->AppendCheckItem( mAID_LOG + 5, _T( "&Info" ) );
	log_menu->AppendCheckItem( mAID_LOG + 6, _T( "C&onfig" ) );
	log_menu->AppendCheckItem( mAID_LOG + 7, _T( "&Fine" ) );
	log_menu->AppendCheckItem( mAID_LOG + 8, _T( "F&iner" ) );
	log_menu->AppendCheckItem( mAID_LOG + 9, _T( "Fi&nest" ) );
	log_menu->AppendCheckItem( mAID_LOG + 10, _T( "Cra&zy" ) );
	chuck_menu->Append( mAID_LOG, _T( "&Log Level" ), log_menu );
	
	chuck_menu->Enable( mAID_ADD, false );
	chuck_menu->Enable( mAID_REMOVE, false );
	chuck_menu->Enable( mAID_REPLACE, false );
	chuck_menu->Enable( mAID_REMOVELAST, false );
	chuck_menu->Enable( mAID_REMOVEALL, false );
	chuck_menu->Enable( mAID_ABORT_CURRENT_SHRED, false );

	window_menu->Append( mAID_WINDOW_VM, _T( "&Virtual Machine Monitor\tCtrl+1" ) );
	window_menu->Append( mAID_WINDOW_CONSOLE, _T( "&Console Monitor\tCtrl+2" ) );
	window_menu_separator = new wxMenuItem( window_menu );

#if wxABI_VERSION > 20600 || !defined( __LINUX__ )
	help_menu->Append( mAID_MINIWEB, _T( "miniAudicle Website..." ) );
	help_menu->Append( mAID_CHUCKWEB, _T( "ChucK Website..." ) );
	help_menu->AppendSeparator();
#endif
	help_menu->Append( wxID_ABOUT, _T( "About miniAudicle" ) );

	this->Append( file_menu, _T( "&File" ) );
	this->Append( edit_menu, _T( "&Edit" ) );
	this->Append( chuck_menu, _T( "&ChucK" ) );
	this->Append( window_menu, _T( "&Window" ) );
	this->Append( help_menu, _T( "&Help" ) );

	last_id = mAID_WINDOW_CONSOLE;
	window_menu_items = 0;
}

mAMenuBar::~mAMenuBar()
{
	// tell the main app to remove this menu bar from its list of menu bars
	// to update, so it wont try to update this instance
	wxGetApp().RemoveMenuBar( this );
}

wxMenu * mAMenuBar::GetFileHistoryMenu()
{
	return file_history_menu;
}

void mAMenuBar::OnVMStart()
{
	vm_on = TRUE;

	chuck_menu->Enable( mAID_ADD, true );
	chuck_menu->Enable( mAID_REMOVE, true );
	chuck_menu->Enable( mAID_REPLACE, true );
	chuck_menu->Enable( mAID_REMOVELAST, true );
	chuck_menu->Enable( mAID_REMOVEALL, true );
	chuck_menu->Enable( mAID_ABORT_CURRENT_SHRED, true );

	chuck_menu->FindItem( mAID_TOGGLE_VM )->SetText( _T( "&Stop Virtual Machine\tAlt+." ) );
#ifdef __WINDOWS_DS__
	chuck_menu->FindItem( mAID_TOGGLE_VM )->Enable( false );
#endif
}

void mAMenuBar::OnVMStop()
{

	vm_on = FALSE;

	chuck_menu->Enable( mAID_ADD, false );
	chuck_menu->Enable( mAID_REMOVE, false );
	chuck_menu->Enable( mAID_REPLACE, false );
	chuck_menu->Enable( mAID_REMOVELAST, false );
	chuck_menu->Enable( mAID_REMOVEALL, false );
	chuck_menu->Enable( mAID_ABORT_CURRENT_SHRED, false );

	chuck_menu->FindItem( mAID_TOGGLE_VM )->SetText( _T( "&Start Virtual Machine\tAlt+." ) );

}

void mAMenuBar::SetLogLevel( t_CKUINT log_level )
{
	for( int i = mAID_LOG; i <= mAID_LOG_HIGHEST; i++ )
	{
		log_menu->Check( i, ( i - mAID_LOG == log_level ) );
    }
}

int mAMenuBar::AddWindow( const wxString & name )
{
	if( window_menu_items == 0 )
		window_menu->Append( window_menu_separator );

	window_menu->Append( ++last_id, name );
	window_menu_items++;

	return last_id;
}

void mAMenuBar::ChangeWindow( int id, const wxString & name )
{
	window_menu->SetLabel( id, name );
}

void mAMenuBar::RemoveWindow( int id )
{
	wxMenuItem * item = window_menu->Remove( id );
	delete item;
	window_menu_items--;
	if( window_menu_items == 0 )
		window_menu->Remove( window_menu_separator );
}

void mAMenuBar::SynchronizeWindowMenuTo( mAMenuBar * menu )
// assumes that window_menu only has the original two items
{
	size_t len = menu->window_menu->GetMenuItemCount(), i = 0;

	if( len > 3 )
	// if the window menu has less than 4 items, there is nothing to synchronize
	{
		if( window_menu_items == 0 )
			window_menu->Append( window_menu_separator );

		for( i = 3; i < len; i++ )
		{
			wxMenuItem * item = menu->window_menu->FindItemByPosition( i );
			window_menu->Append( item->GetId(), item->GetText() );
		}
	}

	window_menu_items = menu->window_menu_items;
	last_id = menu->last_id;
}

