/*
* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  
*
*/


// INCLUDES
#include <alf/alfenv.h>

#include <alf/AlfGridLayout.h>
#include <alf/AlfViewportLayout.h>

#include <alf/alftextvisual.h>
#include <alf/alfimagevisual.h>

#include <alf/AlfTextStyleManager.h>
#include <alf/AlfTextStyle.h>

#include "AlfPerfAppSuiteEPGControl.h"
#include "AlfPerfAppSuiteHelper.h"
#include "AlfPerfAppSuiteTestCaseScroll.h"

// ============================= MEMBER FUNCTIONS ==============================

TInt DurationInMinutes( TTime aStart, TTime aEnd )
	{
	TTimeIntervalMinutes duration;
	aEnd.MinutesFrom( aStart, duration );
	return duration.Int();
	}

TProgram::TProgram()
	{
	iName.Zero();
	}

TProgram::TProgram( const TDesC& aName, const TDesC& aStart, const TDesC& aEnd )
	:iName( aName ),
	iStart( aStart ),
	iEnd( aEnd )
	{
	}

TInt TProgram::DurationInMinutes()
	{
	return ::DurationInMinutes( iStart, iEnd ); 
	}

CAlfPerfAppSuiteEPGControl::CAlfPerfAppSuiteEPGControl(CAlfPerfAppSuiteTestCaseScroll* aScrollControl)
    : iScrollControl(aScrollControl)
	{
	
	}
		
CAlfPerfAppSuiteEPGControl::~CAlfPerfAppSuiteEPGControl()
	{
#ifdef ENABLE_TEXTSTYLES
	CAlfTextStyleManager& styleManager = Env().TextStyleManager();
	for( TInt i=0; i<iTextStyles.Count(); i++ )
		{
		styleManager.DeleteTextStyle( iTextStyles[i] );
		}
	iTextStyles.Close();
#endif	
	}
		
void CAlfPerfAppSuiteEPGControl::ConstructL( 
	        CAlfEnv& aEnv, 
	        const TSize& aVisibleArea,
	        CAlfLayout* aParentLayout )
	{
	iLoadedImages = 0;
	iVisibleArea = aVisibleArea;
	CAlfControl::ConstructL( aEnv );
	
#ifdef ENABLE_TEXTSTYLES
	CreateTextStylesL();
#endif	
	
	// Construct a base layout to add a background
	CAlfLayout* baseLayout = CAlfLayout::AddNewL( *this, aParentLayout );
  	TAlfPerfAppSuiteHelper::AddGradientBrushL( baseLayout, KRgbBlue, KRgbWhite );
  	TAlfPerfAppSuiteHelper::AddDropShadowBrushL( baseLayout, KRgbWhite, 1 );	
	
	// Create grid layout
	CAlfGridLayout* gridLayout = 
		CAlfGridLayout::AddNewL( *this, 1, 1, baseLayout );
	gridLayout->SetPadding( 10 );
	
	// Get texture manager
	CAlfTextureManager& textureManager = Env().TextureManager();
	
    // Add heading row
	CAlfTextVisual* headingTextVisual =	CAlfTextVisual::AddNewL( *this, gridLayout );
	headingTextVisual->SetTextL( _L("Tuubi EPG") );
#ifdef ENABLE_TEXTSTYLES
	headingTextVisual->SetTextStyle( iTextStyles[ETextStyleTitle] );
	headingTextVisual->SetColor( KRgbWhite );
#endif
	RArray<TInt> rowHeights;
	rowHeights.Append( 50 );
	
	// Define time window to show
	TTime start( _L("181500.") );
	TTime end( _L("201500.") );
		
	// HEADER
	RArray<TProgram> programs;
	// NOTE: Programs must start and end at the same time for them to be correctly
	//       aligned on screen. Our total time window here is 24*60 min.
	programs.Append( TProgram( _L("---"),   _L("000000."), _L("174500.") ) );	
	programs.Append( TProgram( _L("18:00"), _L("174500."), _L("181500.") ) );
	programs.Append( TProgram( _L("18:30"), _L("181500."), _L("184500.") ) );
	programs.Append( TProgram( _L("19:00"),	_L("184500."), _L("191500.") ) );
	programs.Append( TProgram( _L("19:30"),	_L("191500."), _L("194500.") ) );
	programs.Append( TProgram( _L("20:00"),	_L("194500."), _L("201500.") ) );
	programs.Append( TProgram( _L("20:30"),	_L("201500."), _L("204500.") ) );
	programs.Append( TProgram( _L("21:00"),	_L("204500."), _L("211500.") ) );
	programs.Append( TProgram( _L("---"),   _L("211500."), _L("235959.") ) );
	TAlfImage empty;
	TInt textStyle = 0;
#ifdef ENABLE_TEXTSTYLES
	textStyle = iTextStyles[ETextStyleTime];
#endif
	AddRowL( gridLayout, empty, programs, start, end, textStyle, EFalse );
    programs.Reset();
    rowHeights.Append( 50 );	


    aEnv.TextureManager().AddLoadObserverL( this );
    
    _LIT( KImage1, "mtv3.png" );
    _LIT( KImage2, "nelonen.png" );
    _LIT( KImage3, "jim.png" );
    _LIT( KImage4, "mtv3_scifi.png" );
    _LIT( KImage5, "discoveryhd.png" );
    _LIT( KImage6, "nationalgeographic.jpg" );
    
	// MTV3
    TAlfImage mtv3Image( 
    		textureManager.LoadTextureL(
    		        KImage1,
    				EAlfTextureFlagRetainResolution,
    				KAlfAutoGeneratedTextureId ) );
    
	programs.Append( TProgram( _L("TV-chät"),
			_L("000000."), _L("180000.") ) );	
	programs.Append( TProgram( _L("Emmerdale"),
			_L("180000."), _L("183000.") ) );
	programs.Append( TProgram( _L("T.i.l.a."),
			_L("183000."), _L("190000.") ) );
	programs.Append( TProgram( _L("Seitsemän Uutiset"),
			_L("190000."), _L("191500.") ) );
	programs.Append( TProgram( _L("Kauppalehden talousuutiset"),
			_L("191500."), _L("192500.") ) );
	programs.Append( TProgram( _L("Päivän sää"),
			_L("192500."), _L("193000.") ) );
	programs.Append( TProgram( _L("Salatut elämät"),
			_L("193000."), _L("200000.") ) );
	programs.Append( TProgram( _L("45min Special: Kuninkaalliset kulissien takana"),
			_L("200000."), _L("210000.") ) );
	programs.Append( TProgram( _L("TV-chät"),
			_L("210000."), _L("235959.") ) );
#ifdef ENABLE_TEXTSTYLES
	textStyle = iTextStyles[ETextStyleProgram];
#endif	
	AddRowL( gridLayout, mtv3Image, programs, start, end, textStyle );
    programs.Reset();
    rowHeights.Append( 100 );
    
    // NELONEN
    TAlfImage nelonenImage( 
    		textureManager.LoadTextureL(
    		        KImage2,
    				EAlfTextureFlagRetainResolution,
    				KAlfAutoGeneratedTextureId ) );
    
	programs.Append( TProgram( _L("TV-chät"),
			_L("000000."), _L("180000.") ) );	
	programs.Append( TProgram( _L("Leijonamies"),
			_L("180000."), _L("183000.") ) );
	programs.Append( TProgram( _L("Tanssi, jos osaat!"),
			_L("183000."), _L("193000.") ) );
	programs.Append( TProgram( _L("Nelosen uutiset"),
			_L("193000."), _L("194500.") ) );
	programs.Append( TProgram( _L("Nelosen sää"),
			_L("194500."), _L("195000.") ) );
	programs.Append( TProgram( _L("IS Urheilu-uutiset"),
			_L("195000."), _L("195500.") ) );
	programs.Append( TProgram( _L("B-Studio"),
			_L("195500."), _L("200000.") ) );
	programs.Append( TProgram( _L("Unelmien poikamies - upseeri ja herrasmies"),
			_L("200000."), _L("210000.") ) );
	programs.Append( TProgram( _L("TV-chät"),
			_L("210000."), _L("235959.") ) );		
#ifdef ENABLE_TEXTSTYLES
	textStyle = iTextStyles[ETextStyleProgram];
#endif	
	AddRowL( gridLayout, nelonenImage, programs, start, end, textStyle );
    programs.Reset();
    rowHeights.Append( 100 );   
    
    // JIM
    TAlfImage jimImage( 
    		textureManager.LoadTextureL(
    		        KImage3,
    				EAlfTextureFlagRetainResolution,
    				KAlfAutoGeneratedTextureId ) );    
	programs.Append( TProgram( _L("TV-chät"),
			_L("000000."), _L("180000.") ) );
	programs.Append( TProgram( _L("Hyvää ruokahalua"),
			_L("180000."), _L("183000.") ) );	
	programs.Append( TProgram( _L("Kiinteistökauppaa maailmalla"),
			_L("183000."), _L("190000.") ) );
	programs.Append( TProgram( _L("Autoklassikot"),
			_L("190000."), _L("193000.") ) );
	programs.Append( TProgram( _L("Huvila & Huussi Extra"),
			_L("193000."), _L("200000.") ) );
	programs.Append( TProgram( _L("Fifth Gear"),
			_L("200000."), _L("203000.") ) );
	programs.Append( TProgram( _L("Fifth Gear"),
			_L("203000."), _L("210000.") ) );
	programs.Append( TProgram( _L("TV-chät"),
			_L("210000."), _L("235959.") ) );		
#ifdef ENABLE_TEXTSTYLES
	textStyle = iTextStyles[ETextStyleProgram];
#endif	
	AddRowL( gridLayout, jimImage, programs, start, end, textStyle );
    programs.Reset();
    rowHeights.Append( 100 );
    
    // MTV3 scifi
    TAlfImage mtv3scifiImage( 
    		textureManager.LoadTextureL(
    		        KImage4,
    				EAlfTextureFlagRetainResolution,
    				KAlfAutoGeneratedTextureId ) );       
	programs.Append( TProgram( _L("TV-chät"),
			_L("000000."), _L("180500.") ) );    
	programs.Append( TProgram( _L("Doctor Who"),
			_L("180500."), _L("183000.") ) );	
	programs.Append( TProgram( _L("Doctor Who"),
			_L("183000."), _L("185500.") ) );
	programs.Append( TProgram( _L("Andromeda"),
			_L("185500."), _L("194000.") ) );
	programs.Append( TProgram( _L("Babylon 5"),
			_L("194000.."), _L("202500.") ) );
	programs.Append( TProgram( _L("Star Trek: Deep Space Nine"),
			_L("202500."), _L("211000.") ) );
	programs.Append( TProgram( _L("TV-chät"),
			_L("211000."), _L("235959.") ) );		
#ifdef ENABLE_TEXTSTYLES
	textStyle = iTextStyles[ETextStyleProgram];
#endif	
	AddRowL( gridLayout, mtv3scifiImage, programs, start, end, textStyle );
    programs.Reset();
    rowHeights.Append( 100 );  
    
    // DISCOVERY HD
    TAlfImage discoveryChannelImage( 
    		textureManager.LoadTextureL(
    		        KImage5,
    				EAlfTextureFlagRetainResolution,
    				KAlfAutoGeneratedTextureId ) );       
	programs.Append( TProgram( _L("TV-chät"),
			_L("000000."), _L("180000.") ) );    
	programs.Append( TProgram( _L("Tuunaajat"),
			_L("180000."), _L("190000.") ) );	
	programs.Append( TProgram( _L("Valmistuksen salat"),
			_L("190000."), _L("193000.") ) );
	programs.Append( TProgram( _L("Valmistuksen salat"),
			_L("193000."), _L("200000.") ) );
	programs.Append( TProgram( _L("Myytinmurtajat"),
			_L("200000.."), _L("210000.") ) );
	programs.Append( TProgram( _L("TV-chät"),
			_L("210000."), _L("235959.") ) );		
#ifdef ENABLE_TEXTSTYLES
	textStyle = iTextStyles[ETextStyleProgram];
#endif	
	AddRowL( gridLayout, discoveryChannelImage, programs, start, end, textStyle );
    programs.Reset();
    rowHeights.Append( 100 );  
    
    // NATIONAL GEOGRAPHIC
    TAlfImage nationalgeographicImage( 
    		textureManager.LoadTextureL(
    		        KImage6,
    				EAlfTextureFlagRetainResolution,
    				KAlfAutoGeneratedTextureId ) );       
	programs.Append( TProgram( _L("TV-chät"),
			_L("000000."), _L("180000.") ) );    
	programs.Append( TProgram( _L("Nat Geo Junior: the Snake Wranglers: Snake Saviour"),
			_L("180000."), _L("183000.") ) );	
	programs.Append( TProgram( _L("Nat Geo Junior: Get Outta Town: Washington Dc"),
			_L("183000."), _L("190000.") ) );
	programs.Append( TProgram( _L("Premiere: Ape Genius"),
			_L("190000."), _L("200000.") ) );
	programs.Append( TProgram( _L("Great Wall of China: Protecting the Dragon"),
			_L("200000.."), _L("210000.") ) );
	programs.Append( TProgram( _L("TV-chät"),
			_L("210000."), _L("235959.") ) );		
#ifdef ENABLE_TEXTSTYLES
	textStyle = iTextStyles[ETextStyleProgram];
#endif	
	AddRowL( gridLayout, nationalgeographicImage, programs, start, end, textStyle );
    programs.Reset();
    rowHeights.Append( 100 );      
    
    // Apply rows
    gridLayout->SetRows( rowHeights.Count() );
    gridLayout->SetRowsL( rowHeights );        
        
    // Set grid size
    gridLayout->SetFlag( EAlfVisualFlagManualSize );
  	TAlfRealSize size;
  	size.iWidth = iVisibleArea.iWidth;
  	for( TInt i=0; i<rowHeights.Count(); i++ )
  		{
  		size.iHeight += rowHeights[i];
  		}
  	gridLayout->SetSize( size, 0 );

  	// Cleanup
  	rowHeights.Close(); 
  	programs.Close();
	}

const TInt KNumberOfImages = 6;
// -----------------------------------------------------------------------------
// Notify observers that all images have been loaded.
// -----------------------------------------------------------------------------
//
void CAlfPerfAppSuiteEPGControl::TextureLoadingCompleted(
        CAlfTexture& /*aTexture*/, TInt /*aTextureId*/, TInt aErrorCode)
    {
    // inform if there is any error
    if( aErrorCode != KErrNone )
        {
        iScrollControl->ImagesLoaded( aErrorCode );
        }
    
    iLoadedImages++;
    if (iLoadedImages == KNumberOfImages)
        {
        iScrollControl->ImagesLoaded( KErrNone );
        }
    }

#ifdef ENABLE_TEXTSTYLES
void CAlfPerfAppSuiteEPGControl::CreateTextStylesL()
	{
	CAlfTextStyleManager& styleManager = Env().TextStyleManager();

    // Create text styles
    for( TInt i=0; i<ENumberOfTextStyles; i++ )
    	{
    	iTextStyles.Append( styleManager.CreatePlatformTextStyleL() );
    	}

    // NOTE: This will leak memory
    // styles are destroyed in TextStyleManager destructor but this is not enough...

    CAlfTextStyle* style = NULL;
    style = styleManager.TextStyle( iTextStyles[ETextStyleTitle] );
    style->SetTextSizeInTwips( 120 );

    style = styleManager.TextStyle( iTextStyles[ETextStyleTime] );
    style->SetTextSizeInTwips( 100 );
    
    style = styleManager.TextStyle( iTextStyles[ETextStyleProgram] );
    style->SetTextSizeInTwips( 80 );    
	}
#endif


void CAlfPerfAppSuiteEPGControl::AddRowL( 
		CAlfLayout* aParentLayout,
		TAlfImage& aChannelImage,
		RArray<TProgram>& aPrograms,
		const TTime& aTimeWindowStart,
		const TTime& aTimeWindowEnd,
		TInt aTextStyle,
		TBool aSetBorders
		)
	{
	// Create grid layout
	CAlfGridLayout* gridLayout = 
		CAlfGridLayout::AddNewL( *this, 1, 1, aParentLayout );
	
	// Set borders
	if( aSetBorders )
		{
		TAlfPerfAppSuiteHelper::AddBorderBrushL( gridLayout, KRgbWhite );
		}	

    // Add channel image
    CAlfImageVisual* imageVisual = CAlfImageVisual::AddNewL( *this, gridLayout );
    imageVisual->SetImage( aChannelImage );
    imageVisual->SetScaleMode( CAlfImageVisual::EScaleFitInside );   
    imageVisual->SetPadding( 2 );
    RArray<TInt> columnWeights;
    columnWeights.Append( 1 );

    // Add programs
    AddProgramsL( gridLayout, aPrograms, aTimeWindowStart, aTimeWindowEnd, aTextStyle, aSetBorders );
    columnWeights.Append( 9 );
        
    // Apply columns
	gridLayout->SetColumns( columnWeights.Count() );
	gridLayout->SetColumnsL( columnWeights );        
	    
	// Cleanup
	columnWeights.Close();        
	}

void CAlfPerfAppSuiteEPGControl::AddProgramsL( 
		CAlfLayout* aParentLayout,
		RArray<TProgram>& aPrograms,
		const TTime& aTimeWindowStart,
		const TTime& aTimeWindowEnd,
		TInt aTextStyle,
		TBool aSetBorders
		)
	{
	
	// Use viewport layout as a base layout
	CAlfViewportLayout* viewPortLayout 
		= CAlfViewportLayout::AddNewL( *this, aParentLayout );
	
	// Set borders
	if( aSetBorders )
		{
		TAlfPerfAppSuiteHelper::AddBorderBrushL( viewPortLayout, KRgbWhite );
		}
	
	// Virtual size is 1,1 which represents a 24*60 minute time window.
	viewPortLayout->SetVirtualSize( TAlfRealSize(1.0f,1.0f), 0 );
	
	// Calculate how much is visible by the time window.
	TReal32 displayWindowSize = DurationInMinutes( aTimeWindowStart, aTimeWindowEnd );
	TReal32 maxWindowSize = 24*60;
	TReal32 relelativeWindowSize = displayWindowSize / maxWindowSize;
	viewPortLayout->SetViewportSize( TAlfRealSize( relelativeWindowSize, 1.0f ), 0 );
	
	// Calculate the offset from beginning.
	TReal32 displayWindowOffset = DurationInMinutes( aPrograms[0].iStart, aTimeWindowStart );
	TReal32 pos = displayWindowOffset / maxWindowSize;
	viewPortLayout->SetViewportPos( TAlfRealPoint( pos, 0.0f ), 0 );
	
	// Create grid layout
	CAlfGridLayout* gridLayout = 
		CAlfGridLayout::AddNewL( *this, aPrograms.Count(), 1, viewPortLayout );

	// Add the programs using the duration of the program as column weight.
	RArray<TInt> columnWeights;
	for( TInt i=0; i<aPrograms.Count(); i++ )
		{
		CAlfTextVisual* textVisual = CAlfTextVisual::AddNewL( *this, gridLayout );
		textVisual->SetTextL( aPrograms[i].iName );
#ifdef ENABLE_TEXTSTYLES
		textVisual->SetTextStyle( aTextStyle );
#endif
		textVisual->SetWrapping( CAlfTextVisual::ELineWrapBreak );
		if( aSetBorders )
			{
			TAlfPerfAppSuiteHelper::AddBorderBrushL( textVisual, TRgb(0xdddddd) );
			}		
		columnWeights.Append( aPrograms[i].DurationInMinutes() );
		}
	
	// Set column weights
	gridLayout->SetColumnsL( columnWeights );
	
	// Cleanup
	columnWeights.Close();
	}
