// -----------------------------------------------------------------------------
// CMediatorServerCommandHandler::CancelCommands
//  
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMediatorServerCommandHandler::CancelCommands( MMediatorCommandObserver* aObserver,
                                                    MMediatorCommandResponseObserver* aResponseObserver )
    {
    LOG(_L("[Mediator Server]\t CMediatorServerCommandHandler::CancelCommand"));
    
    // loop through list of pending commands
    for ( TInt i = iCommandPendingList.Count()-1; i >= 0; i-- )
        {
        
        CCommand* commandPtr = iCommandPendingList[i];
        
        if ( commandPtr )
            {
            
            TBool commandCanceled = EFalse;
            
            // This client has registered the command, and some other client has issued it
            // -> give an error response to the issuer
            if ( aObserver == commandPtr->Observer() )
                {
                TRAP_IGNORE( commandPtr->ResponseObserver()->CommandResponseL( commandPtr->Domain(),
                                                                               commandPtr->Category(),
                                                                               commandPtr->Id(),
                                                                               KErrMediatorCommandRemoved,
                                                                               KNullDesC8 ) );
                commandCanceled = ETrue;                                                                               
                }
            
            // This client has issued the command
            // -> inform the client which registered the command that it is canceled
            if ( aResponseObserver == commandPtr->ResponseObserver() )
                {
                TRAP_IGNORE( commandPtr->Observer()->CancelMediatorCommandL( commandPtr->Domain(),
                                                                             commandPtr->Category(),
                                                                             commandPtr->Id() ) );
                commandCanceled = ETrue;                                                                             
                }
            
            // pending command was registered and/or issued by this client, so now it can be removed
            // from the list
            if ( commandCanceled )
                {
                iCommandPendingList.Remove( i );
                delete commandPtr;
                }
            
            }
        
        }

    }
// -----------------------------------------------------------------------------
// CMediatorServerCommandHandler::TimerCallBack
//  
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMediatorServerCommandHandler::TimerCallBack( TUid aDomain, 
                                                   TUid aCategory, 
                                                   TInt aCommandId )
    {
    LOG(_L("[Mediator Server]\t CMediatorServerCommandHandler::TimerCallBack"));
    TBool found = EFalse;
    for ( TInt index = 0; index < iCommandPendingList.Count() && !found; index ++ )
        {
        CCommand* commandPtr = iCommandPendingList[index];
        if ( commandPtr )
            {
            if ( ( aDomain == commandPtr->Domain() )
                 && ( aCategory == commandPtr->Category() )
                 && ( aCommandId == commandPtr->Id() ) )
                {
                // We have found the correct command --> ignore the leave 
                // Send the response to initiator with timeout error
                TRAP_IGNORE( commandPtr->ResponseObserver()->CommandResponseL( aDomain,
                                                                               aCategory,
                                                                               aCommandId,
                                                                               KErrMediatorTimeout,
                                                                               KNullDesC8 ) );
                // And clear the responder side also                                                                  
                TRAP_IGNORE( commandPtr->Observer()->MediatorCommandTimeoutL( aDomain,
                                                                              aCategory,
                                                                              aCommandId ) );                                                                  
                // Remove the command from list, free memory && stop looping
                iCommandPendingList.Remove( index );
                delete commandPtr;
                commandPtr = NULL;
                found = ETrue;                                                                  
                }
            }
        }
    }
// -----------------------------------------------------------------------------
// CMediatorServerCommandHandler::CancelCommandL
//  
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMediatorServerCommandHandler::CancelCommand( 
                                        TMediatorCategory aCategory, 
                                        MediatorService::TCommand aCommand )
    {
    LOG(_L("[Mediator Server]\t CMediatorServerCommandHandler::CancelCommand"));
    TBool found = EFalse;
    for ( TInt index = 0; index < iCommandPendingList.Count() && !found; index ++ )
        {
        CCommand* commandPtr = iCommandPendingList[index];
        if ( commandPtr )
            {
            TUid domain = aCategory.iDomain;
            TUid category = aCategory.iCategory;
            TInt commandId = aCommand.iCommandId;
            if ( ( domain == commandPtr->Domain() )
                 && ( category == commandPtr->Category() )
                 && ( commandId == commandPtr->Id() ) )
                {
                // We have found the correct command --> cancel it 
                TRAP_IGNORE( commandPtr->Observer()->CancelMediatorCommandL( domain,
                                                                             category,
                                                                             commandId ) );
                // Remove the command from list, free memory && stop looping
                iCommandPendingList.Remove( index );
                delete commandPtr;
                commandPtr = NULL;
                found = ETrue;                                                                  
                }
            }
        }
    }
// -----------------------------------------------------------------------------
// CMediatorServerCommandHandler::IssueResponse
//  
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CMediatorServerCommandHandler::IssueResponse( 
                                        TMediatorCategory aCategory, 
                                        MediatorService::TCommand aCommand,
                                        const TDesC8& aData,
                                        TInt aStatus )
    {
    LOG(_L("[Mediator Server]\t CMediatorServerCommandHandler::IssueResponse"));
    TBool found = EFalse;
    for ( TInt index = 0; index < iCommandPendingList.Count() && !found; index ++ )
        {
        CCommand* commandPtr = iCommandPendingList[index];
        if ( commandPtr )
            {
            TUid domain = aCategory.iDomain;
            TUid category = aCategory.iCategory;
            TInt commandId = aCommand.iCommandId;
            if ( ( domain == commandPtr->Domain() )
                 && ( category == commandPtr->Category() )
                 && ( commandId == commandPtr->Id() ) )
                {
                // We have found the correct command --> ignore the leave 
                TRAP_IGNORE( commandPtr->ResponseObserver()->CommandResponseL( domain,
                                                                               category,
                                                                               commandId,
                                                                               aStatus,
                                                                               aData ) );
                // Remove the command from list, free memory && stop looping
                iCommandPendingList.Remove( index );
                delete commandPtr;
                commandPtr = NULL;
                found = ETrue;                                                                  
                }
            }
        }

    if ( !found )
        {
        ERROR_TRACE(Print(_L("[Mediator] CMediatorServerCommandHandler::IssueResponse: Command %d not found in category %d of domain %d\n"), aCommand.iCommandId, 
                                                                                                                                             aCategory.iDomain.iUid ) );    
        }
            
    return found ? KErrNone : KErrMediatorCommandNotFound;

    }
// -----------------------------------------------------------------------------
// CMediatorServerObjectHandler::ClearRegistrations
//  
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//  
void CMediatorServerObjectHandler::ClearRegistrations( 
                          MMediatorServerEventObserver* aEventObserver, 
                          MMediatorCommandObserver* aCommandObserver,
                          MMediatorServerNotificationObserver* aNotifObserver )
    {
    LOG(_L("[Mediator Server]\t CMediatorServerObjectHandler::ClearRegistrationsL"));
    
    // Clear all pending subscriptions -- loop through domains
    for ( TInt index = iDomainList.Count()-1; index >= 0; index-- )
        {
        CDomain* domainPtr = iDomainList[index];
        if ( domainPtr )
            {
            // Loop through categories
            for( TInt index2 = domainPtr->CategoryCount()-1; index2 >= 0; index2-- )
                {
                CCategory* categoryPtr = domainPtr->GetCategory( index2 );
                if ( categoryPtr )
                    {
                    // Loop through events within category
                    for ( TInt index3 = categoryPtr->EventCount()-1; index3 >= 0; index3-- )
                        {
                        CEvent* eventPtr = categoryPtr->GetEvent( index3 );
                        if ( eventPtr )
                            {
                            // Unregister if found --> ignore the return value
                            eventPtr->RemoveObserver( aEventObserver );
                            }
                        eventPtr = NULL;
                        }
                    RCommandList removedCommands;
                    // Loop through commands within category
                    for ( TInt index4 = categoryPtr->CommandCount()-1; index4 >= 0; index4-- )
                        {
                        CCommand* commandPtr = categoryPtr->GetCommand( index4 );
                        if ( commandPtr )
                            {
                            if ( commandPtr->Observer() == aCommandObserver )
                                {
                                // Found the command --> remove it and append
                                // to notification list
                                TCommand removeCommand;
                                removeCommand.iCommandId = commandPtr->Id();
                                removeCommand.iVersion = commandPtr->Version();
                                removedCommands.Append( removeCommand );
                                categoryPtr->RemoveCommand( index4 );
                                delete commandPtr;
                                commandPtr = NULL;
                                }
                            }
                        commandPtr = NULL;
                        }
                    // Notify command removal
                    if ( removedCommands.Count() > 0 )
                        {
                        CommandsRemoved( domainPtr->DomainUid(),
                                         categoryPtr->CategoryUid(),
                                         removedCommands );
                        }
                    removedCommands.Reset();
                    }
                categoryPtr = NULL;
                }
            }
        domainPtr = NULL;
        }
    
    // Loop through the notification subscriber array still
    TBool found = EFalse;
    for ( TInt index = 0; index < iObserverList.Count() && !found; index++ )
        {
        if ( iObserverList[index] == aNotifObserver )
            {
            iObserverList.Remove( index );
            found = ETrue;
            }
        }
    }
// -----------------------------------------------------------------------------
// CMediatorServerCommandHandler::RegisterCommandListL
//  
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CMediatorServerCommandHandler::RegisterCommandListL( 
                TMediatorCategory aCategory, 
                const RCommandList& aCommands,
                TSecureId aSecureId,
                MMediatorCommandObserver* aObserver )
    {
    LOG(_L("[Mediator Server]\t CMediatorServerCommandHandler::RegisterCommandListL"));
    // Check that domain exists --> if not add new
    CDomain* domain = iObjectHandler.FindDomain( aCategory.iDomain );
    if ( !domain )
        {
        domain = iObjectHandler.AddDomainL( aCategory.iDomain );
        }
    
    // Check that category exists --> if not add new
    TInt ignore = 0; // not used here    
    CCategory* category = domain->FindCategory( aCategory.iCategory, ignore );
    if ( !category )
        {
        category = domain->AddCategoryL( aCategory.iCategory );
        }
    
    // Loop through the commands and add them to list
    // Take the possible error to variable
    TInt error = KErrNone;
    TBool stop = EFalse;
    TInt index = 0;
    for ( index = 0; index < aCommands.Count() && !stop; index++ )
        {
        CCommand* newCommand = CCommand::NewL( aCommands[index] );
        CleanupStack::PushL( newCommand );
        newCommand->SetSecureId( aSecureId );   // For unregistering
        newCommand->SetObserver( aObserver );   // For getting the commands
        newCommand->SetCommitState( CItem::EAdded ); // For transaction handling
        TInt addError = category->AddCommand( newCommand );
        if ( addError )
            {
            ERROR_TRACE(Print(_L("[Mediator] CMediatorServerCommandHandler::RegisterCommandListL: addError=%d\n"), addError ) );
            ERROR_TRACE(Print(_L("[Mediator] Failed to add command %d to category %d of domain %d\n"), newCommand->Id(), 
                                                                                                       aCategory.iCategory.iUid,
                                                                                                       aCategory.iDomain.iUid ) );
            // in case of error, delete event and take error
            CleanupStack::PopAndDestroy( newCommand );
            error = addError;
            stop = ETrue;
            }
        else
            {
            // Event has been added properly --> just pop
            CleanupStack::Pop( newCommand );
            }     
        newCommand = NULL;
        }  
    
    TRACE(Print(_L("[Mediator Server]\t Commands registered:\n")));
    TRACE(Print(_L("[Mediator Server]\t Success/count: %d/%d \tstatus: %d"), index, aCommands.Count(), error ));    
    
    // Check error if we need to do partial recovery
    if ( error != KErrNone ) 
        {
        // Remove the registered commands
        category->RollbackCommands();
        }
    else
        {
        // Complete command registration
        category->CommitCommands();
        
        // Use the object handler to notify command registration
        iObjectHandler.CommandsAdded( aCategory.iDomain, 
                                      aCategory.iCategory, 
                                      aCommands );
        }
    // In the end leave if error --> client gets error code
    User::LeaveIfError( error );
    }