/*
========================================================================
 Name        : AudioPlayerContainerView.cpp
 Copyright   : Symbian Academy, 2007
 Description : Handles the user interface and interaction for the main view.
 ============================================================================
 */
// [[[ begin generated region: do not modify [Generated System Includes]
#include <aknviewappui.h>
#include <eikmenub.h>
#include <avkon.hrh>
#include <akncontext.h>
#include <akntitle.h>
#include <stringloader.h>
#include <barsread.h>
#include <eikbtgpc.h>
#include <AudioPlayer.rsg>
// ]]] end generated region [Generated System Includes]
#include <akncommondialogs.h>

// [[[ begin generated region: do not modify [Generated User Includes]
#include "AudioPlayer.hrh"
#include "AudioPlayerContainerView.h"
#include "AudioPlayerContainer.hrh"
#include "AudioPlayerContainer.h"
// ]]] end generated region [Generated User Includes]

// [[[ begin generated region: do not modify [Generated Constants]
// ]]] end generated region [Generated Constants]

/**
 * First phase of Symbian two-phase construction. Should not contain any
 * code that could leave.
 */
CAudioPlayerContainerView::CAudioPlayerContainerView()
	{
	// [[[ begin generated region: do not modify [Generated Contents]
	iAudioPlayerContainer = NULL;
	// ]]] end generated region [Generated Contents]

	}
/** 
 * The view's destructor removes the container from the control
 * stack and destroys it.
 */
CAudioPlayerContainerView::~CAudioPlayerContainerView()
	{
	// [[[ begin generated region: do not modify [Generated Contents]
	delete iAudioPlayerContainer;
	iAudioPlayerContainer = NULL;
	// ]]] end generated region [Generated Contents]

	delete iAudioEngine;
	}

/**
 * Symbian two-phase constructor.
 * This creates an instance then calls the second-phase constructor
 * without leaving the instance on the cleanup stack.
 * @return new instance of CAudioPlayerContainerView
 */
CAudioPlayerContainerView* CAudioPlayerContainerView::NewL()
	{
	CAudioPlayerContainerView* self = CAudioPlayerContainerView::NewLC ();
	CleanupStack::Pop ( self);
	return self;
	}

/**
 * Symbian two-phase constructor.
 * This creates an instance, pushes it on the cleanup stack,
 * then calls the second-phase constructor.
 * @return new instance of CAudioPlayerContainerView
 */
CAudioPlayerContainerView* CAudioPlayerContainerView::NewLC()
	{
	CAudioPlayerContainerView* self = new ( ELeave ) CAudioPlayerContainerView();
	CleanupStack::PushL ( self);
	self->ConstructL ();
	return self;
	}

/**
 * Second-phase constructor for view.  
 * Initialize contents from resource.
 */
void CAudioPlayerContainerView::ConstructL()
	{
	// [[[ begin generated region: do not modify [Generated Code]
	BaseConstructL ( R_AUDIO_PLAYER_CONTAINER_AUDIO_PLAYER_CONTAINER_VIEW);
	// ]]] end generated region [Generated Code]

	// add your own initialization code here
	iAudioEngine = CAudioPlayerEngine::NewL ();
	}

/**
 * @return The UID for this view
 */
TUid CAudioPlayerContainerView::Id() const
	{
	return TUid::Uid ( EAudioPlayerContainerViewId);
	}

/**
 * Handle a command for this view (override)
 * @param aCommand command id to be handled
 */
void CAudioPlayerContainerView::HandleCommandL( TInt aCommand)
	{
	// [[[ begin generated region: do not modify [Generated Code]
	TBool commandHandled = EFalse;
	switch ( aCommand)
		{ // code to dispatch to the AknView's menu and CBA commands is generated here
		case EAudioPlayerContainerViewPlay_fileMenuItemCommand:
			commandHandled = HandlePlay_fileMenuItemSelectedL ( aCommand);
			break;
		case EAudioPlayerContainerViewPlay_last_fileMenuItemCommand:
			commandHandled = HandlePlay_last_fileMenuItemSelectedL ( aCommand);
			break;
		case EAudioPlayerContainerViewStopMenuItemCommand:
			commandHandled = HandleStopMenuItemSelectedL ( aCommand);
			break;
		case EAudioPlayerContainerViewExitMenuItemCommand:
			commandHandled = HandleExitMenuItemSelectedL ( aCommand);
			break;
		default:
			break;
		}

	if ( !commandHandled)
		{

		if ( aCommand == EAknSoftkeyExit)
			{
			AppUi()->HandleCommandL ( EEikCmdExit);
			}

		}
	// ]]] end generated region [Generated Code]

	}

/**
 *	Handles user actions during activation of the view, 
 *	such as initializing the content.
 */
void CAudioPlayerContainerView::DoActivateL(const TVwsViewId& /*aPrevViewId*/,
		TUid /*aCustomMessageId*/, const TDesC8& /*aCustomMessage*/)
	{
	// [[[ begin generated region: do not modify [Generated Contents]
	SetupStatusPaneL ();

	CEikButtonGroupContainer* cba = AppUi()->Cba ();
	if ( cba != NULL)
		{
		cba->MakeVisible ( EFalse);
		}

	if ( iAudioPlayerContainer == NULL)
		{
		iAudioPlayerContainer = CAudioPlayerContainer::NewL ( ClientRect (),
		NULL, this);
		iAudioPlayerContainer->SetMopParent ( this);
		AppUi()->AddToStackL ( *this, iAudioPlayerContainer);
		}
	// ]]] end generated region [Generated Contents]

	}

/**
 */
void CAudioPlayerContainerView::DoDeactivate()
	{
	// [[[ begin generated region: do not modify [Generated Contents]
	CleanupStatusPane ();

	CEikButtonGroupContainer* cba = AppUi()->Cba ();
	if ( cba != NULL)
		{
		cba->MakeVisible ( ETrue);
		cba->DrawDeferred ();
		}

	if ( iAudioPlayerContainer != NULL)
		{
		AppUi()->RemoveFromViewStack ( *this, iAudioPlayerContainer);
		delete iAudioPlayerContainer;
		iAudioPlayerContainer = NULL;
		}
	// ]]] end generated region [Generated Contents]

	}

// [[[ begin generated function: do not modify
void CAudioPlayerContainerView::SetupStatusPaneL()
	{
	// reset the context pane
	TUid contextPaneUid = TUid::Uid ( EEikStatusPaneUidContext);
	CEikStatusPaneBase::TPaneCapabilities subPaneContext =StatusPane()->PaneCapabilities ( contextPaneUid);
	if ( subPaneContext.IsPresent ()&& subPaneContext.IsAppOwned ())
		{
		CAknContextPane* context = static_cast< CAknContextPane* > (
				StatusPane()->ControlL( contextPaneUid ) );
		context->SetPictureToDefaultL ();
		}

	// setup the title pane
	TUid titlePaneUid = TUid::Uid ( EEikStatusPaneUidTitle);
	CEikStatusPaneBase::TPaneCapabilities subPaneTitle =StatusPane()->PaneCapabilities ( titlePaneUid);
	if ( subPaneTitle.IsPresent ()&& subPaneTitle.IsAppOwned ())
		{
		CAknTitlePane* title = static_cast< CAknTitlePane* >(
				StatusPane()->ControlL( titlePaneUid ) );
		TResourceReader reader;
		iEikonEnv->CreateResourceReaderLC( reader, R_AUDIO_PLAYER_CONTAINER_TITLE_RESOURCE );
		title->SetFromResourceL ( reader);
		CleanupStack::PopAndDestroy (); // reader internal state
		}

	}
// ]]] end generated function

// [[[ begin generated function: do not modify
void CAudioPlayerContainerView::CleanupStatusPane()
	{
	}
// ]]] end generated function

/** 
 * Handle status pane size change for this view (override)
 */
void CAudioPlayerContainerView::HandleStatusPaneSizeChange()
	{
	CAknView::HandleStatusPaneSizeChange ();

	// this may fail, but we're not able to propagate exceptions here
	TInt result;
	TRAP( result, SetupStatusPaneL() );
	}

/** 
 * Handle the selected event.
 * @param aCommand the command id invoked
 * @return ETrue if the command was handled, EFalse if not
 */
TBool CAudioPlayerContainerView::HandleExitMenuItemSelectedL( TInt aCommand)
	{
	AppUi()->HandleCommandL ( EEikCmdExit);
	return ETrue;
	}

/** 
 * Handle the selected event.
 * @param aCommand the command id invoked
 * @return ETrue if the command was handled, EFalse if not
 */
TBool CAudioPlayerContainerView::HandlePlay_fileMenuItemSelectedL( TInt aCommand)
	{
	// Display the file selection dialog
	TFileName filename(KNullDesC);
	_LIT(KTitle, "Select audio file");
	if ( AknCommonDialogs::RunSelectDlgLD (filename, R_FILE_SELECT_DIALOG,
			KTitle))
		{
		// User selected a file, send it to the audio engine
		iAudioEngine->PlayFileL (filename);
		// Edit 27: Save the last played file name.
		//          Call the SaveDataFileL() method. You can use
		//          the KDataFilename literal, which is defined in the
		//          header file of this class.

		}
	return ETrue;
	}

/** 
 * Handle the selected event.
 * @param aCommand the command id invoked
 * @return ETrue if the command was handled, EFalse if not
 */
TBool CAudioPlayerContainerView::HandlePlay_last_fileMenuItemSelectedL(
		TInt aCommand)
	{
	// Edit 39: Read the data file (KDataFilename) into a HBufC* variable.

	
	// Edit 40: Send the descriptor to the PlayFileL() method of the
	//          audio engine. Use * to dereference the HBufC* when
	//          passing it to the method as a parameter.


	// Edit 41: Pop and destroy the filename from the cleanup stack.
	//          Remember that the read method left it on the stack, as
	//          indicated by the trailing C of the function name.

	
	return ETrue;
	}

/** 
 * Handle the selected event.
 * @param aCommand the command id invoked
 * @return ETrue if the command was handled, EFalse if not
 */
TBool CAudioPlayerContainerView::HandleStopMenuItemSelectedL( TInt aCommand)
	{
	if ( iAudioEngine)
		iAudioEngine->StopPlay ();
	return ETrue;
	}

void CAudioPlayerContainerView::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane)
	{
	if ( aResourceId == R_AUDIO_PLAYER_CONTAINER_MENU_PANE1_MENU_PANE)
		{
		if ( iAudioEngine->IsPlaying ())
			{
			// We're playing, so don't display the play commands
			aMenuPane->SetItemDimmed (EAudioPlayerContainerViewPlay_fileMenuItemCommand, ETrue);
			aMenuPane->SetItemDimmed (EAudioPlayerContainerViewPlay_last_fileMenuItemCommand, ETrue);
			}
		else
			{
			// We're not playing, so don't display stop command.
			aMenuPane->SetItemDimmed (EAudioPlayerContainerViewStopMenuItemCommand, ETrue);
			}
		}
	}

// Edit 15b: Implement the SaveDataFileL()-method


	// Edit 16: Define a variable called fsSession for the file server
	//          session and establish the connection. Leave if this does 
	//          not complete successfully.


    
    // Edit 17: Push the session on the cleanup stack with the correct function
    //          that closes the session in case of a leave.

    
    // Edit 18: Create the private folder on drive C in case it doesn't exist yet.
    //          This can be done through the CreatePrivatePath() method of
    //          the file server session. The drives are enumerated, use EDriveC.
    //          Ignore the return value; if there will be problems with creating
    //          the file, the file creation method will fail.

    
    // Edit 19: Make sure the standard session path is set to our private directory.
    //          Use the SetSessionToPrivate(EDriveC)-method of the file server
    //          session. Leave if there is a problem.

    
    // Edit 20: Create a file object

    
    // Edit 21: Create / replace the file and leave if there is a problem.
    //          Use the aFilename parameter for the file name and open
    //          the file in write mode.

    
    // Edit 22: Push the file onto the cleanup stack (remember that it's an 
    //          R type class as well!)


	// Edit 23: Create a file write stream based on the file.
    //          The class name is RFileWriteStream. Look up the required header
    //          file for using this class in the SDK documentation.

    
    // Edit 24: Push the file write stream on the cleanup stack (R type class)

    
    // Edit 25: Externalize the data to the stream. We'll use the same method 
    //          for interanlizing and therefore don't have to do any 
    //          Unicode <-> 8bit conversion.
    //          Note that the externalization operator can cause a leave,
    //          so the cleanup stack was necessary for the involved objets.


	// Edit 26: Call the commit method of the file write stream to ensure that
	//          its contents are written to the file.
    
    
    // Edit 26: Pop and destroy all three objects from the cleanup stack.


// Edit 29b: Implement the ReadFileLC() method.


	// Edit 30: Like in the save method, create a file server session object
	//          and establish a connection. Then, push the file server
	//          session onto the cleanup stack.
	//          Note: In a real application, you shouldn't connect to the
	//          file server every time, as this incurs quite a lot of overhead.
	//          Instead, you should save the session as an instance variable
	//          and reuse it as often as possible - or even use a file server
	//          session that was created automatically by the UI framework.
	
	
	// Edit 31: Set the session path to the private directory on drive C.
	
	
	// Edit 32: Define an RFile object and open the aFilename for
	//          reading.
	
	
	// Edit 33: Push the file object on the cleanup stack.
	
	
	// Edit 34: Get the size of the content so that we can set the maximum
	//          size for the internalisation of the HBufC. To do this,
	//          define a TInt called fileSize. Then, use the Size() method
	//          of the file to get its size. You should leave if the Size()
	//          method returns an error code.
	
	
	// Edit 35: Create a file read stream based on the file object and
	//          push it on the cleanup stack.
	
	
	// Edit 36: Allocate a HBufC* descriptor based on the input stream, with the
	//          fileSize as the maximum size. Use the NewL() method of the
	//          HBufC class, which can directly accept the stream as the first
	//          parameter and the maximum size as the second.
	//          Note that we don't push the descriptor on the cleanup stack
	//          yet, as we have to remove the three other classes from the 
	//          cleanup stack before we can add the HBufC - which should remain 
	//          there when returning from this method. After all, it's a stack
	//          and we can't leave the HBufC on the top of the stack and remove 
	//          the three objects below it.
	
	
	// Edit 37: Pop and destroy the three objects (stream, file, session)
	//          from the cleanup stack.
	
	
	// Edit 38: The ReadFileLC() method has a trailing C, so the newly created
	//          HBufC* should stay on the cleanup stack.
	//          Therefore, push it on the stack again!
	//          Finally, return the buffer to the caller.

