// EIKFORM.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <eikform.h>
#include <eikfctry.h>
#include <eikcapc.h>
#include <eikcapca.h>
#include <eikform.pan>
#include <coemain.h>


GLDEF_C void Panic(TEikFormPanic aPanic)
	{
	User::Panic(_L("EIKON-FORM"),aPanic);
	}

EXPORT_C CEikForm::CEikForm()
	: iCurrentLine(-1)
	{}

EXPORT_C CEikForm::~CEikForm()
	{
	delete(iLines);
	}

EXPORT_C CCoeControl* CEikForm::CreateLineByTypeL(const TDesC& aCaption,TInt aControlId,TInt aControlType,TAny* aReturnValue)
	{
	CEikCaptionedControl* line=new(ELeave) CEikCaptionedControl;
	CleanupStack::PushL(line);
	iLines->AppendL(line);
	CleanupStack::Pop();
	ConstructByTypeL(aControlType,line,this);
	line->SetCaptionL(aCaption);
	line->iId=aControlId;
	line->iReturnValue=aReturnValue;
	return(line->iControl);
	}

EXPORT_C void CEikForm::ConstructByTypeL(TInt aType,CEikCaptionedControl* aLine,CCoeControl* aContainer)
	{
	SEikControlInfo controlInfo=EikControlFactory::CreateByTypeL(aType);
    if (!controlInfo.iControl)
        controlInfo=CreateCustomControlL(aType);
    aLine->iControl=controlInfo.iControl;
	aLine->iControlType=aType;
    aLine->SetContainerWindowL(*aContainer);
	aLine->CopyControlContextFrom(aContainer);
    aLine->SetObserver(this);
    controlInfo.iControl->SetContainerWindowL(*aContainer);
    controlInfo.iControl->SetObserver(this);
	controlInfo.iControl->CopyControlContextFrom(aContainer);
	if (controlInfo.iFlags&EEikControlHasEars)
		aLine->SetUsesEars();
	if (controlInfo.iFlags&EEikControlIsNonFocusing)
		{
		aLine->SetNonFocusing();
		controlInfo.iControl->SetNonFocusing();
		}
	if (controlInfo.iFlags&EEikControlHasExtraAscent)
		aLine->SetExtraAscent();
	if (controlInfo.iTrailerTextId)
		{
		TBuf<40> tmp;
	    iCoeEnv->ReadResource(tmp,controlInfo.iTrailerTextId);
		aLine->SetTrailerL(tmp);
		}
	}

EXPORT_C SEikControlInfo CEikForm::CreateCustomControlL(TInt /*aControlType*/)
    {
    Panic(EEikFormPanicUnknownControlType);
	SEikControlInfo controlInfo;
    return controlInfo;
    }

EXPORT_C void CEikForm::GetCustomAutoValue(TAny* /*aReturnValue*/,TInt /*aControlType*/,const CCoeControl* /*aControl*/)
	{
	Panic(EEikFormPanicUnknownGetAutoType);
	}

EXPORT_C CCoeControl* CEikForm::ComponentControl(TInt aIndex) const
    {
    return((*iLines)[aIndex]);
    }

EXPORT_C TInt CEikForm::CountComponentControls() const
	{
	return(iLines->Count());
	}

EXPORT_C void CEikForm::SizeChangedL()
    {
	TRect rect=iBorder.InnerRect(Rect());
	iLines->SetRectL(rect);
    }

EXPORT_C TSize CEikForm::MinimumSize()
    {
	return(iLines->MinimumSize()+iBorder.SizeDelta());
    }

EXPORT_C void CEikForm::HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType)
    {
    switch (aEventType)
        {
    case EEventPrepareFocusTransition:
        PrepareForFocusTransitionL();
        break;
    case EEventRequestFocus:
	    ChangeFocusTo(FindLineIndex(aControl));
        break;
    default:
        break;
        }
    }

EXPORT_C void CEikForm::PrepareForFocusTransitionL()
    {
    if (iCurrentLine<0)
        return;
    (*iLines)[iCurrentLine]->iControl->PrepareForFocusLossL();
    }

EXPORT_C void CEikForm::ShowFocus(TBool aFocus)
	{
	if (iCurrentLine>=0)
	    (*iLines)[iCurrentLine]->SetCurrent(aFocus);
	}

EXPORT_C void CEikForm::ChangeFocusTo(TInt aCurrentLine)
    {
    if (aCurrentLine==iCurrentLine)
        return;
	ShowFocus(EFalse);
    iCurrentLine=aCurrentLine;
	ShowFocus(ETrue);
    }

EXPORT_C TInt CEikForm::FindLineIndex(CCoeControl* aControl) const
	{ // only finds on the current page - only *needs* to find there
	return(iLines->FindLineIndex(aControl));
	}

EXPORT_C TInt CEikForm::IdOfFocusControl() const
	{
	if (iCurrentLine<0)
		return(0);
	return((*iLines)[iCurrentLine]->iId);
	}

EXPORT_C TBool CEikForm::RotateFocusByL(TInt aDelta)
    {
	if (iLines->Count() == 0)
		return(EFalse);
    TInt max=iLines->Count()-1;
	TInt count=iLines->Count();
	TInt currentLine=iCurrentLine;
	while (count--)
		{
		currentLine+=aDelta;
    	if (currentLine<0)
        	currentLine=max;
    	else if (currentLine>max)
        	currentLine=0;
		CEikCaptionedControl* line=(*iLines)[currentLine];
		if (line->IsNonFocusing() || line->IsDimmed() || !(line->IsVisible()))
			continue;
    	PrepareForFocusTransitionL();
		if (line->IsNonFocusing() || line->IsDimmed() || !(line->IsVisible()))
			continue;
    	ChangeFocusTo(currentLine);
    	return(ETrue);
		}
    return(EFalse);
    }

EXPORT_C void CEikForm::SetControlCaptionL(TInt aControlId,const TDesC& aText)
    {
    CEikLabel* caption=ControlCaption(aControlId);
	caption->SetTextL(aText);
	caption->DrawNow();
    }

EXPORT_C void CEikForm::SetControlCaptionL(TInt aControlId,TInt aResourceId)
    {
    TBuf<80> tmp;
    iCoeEnv->ReadResource(tmp,aResourceId);
    SetControlCaptionL(aControlId,tmp);
    }

EXPORT_C CEikLabel* CEikForm::ControlCaption(TInt aControlId) const
    {
    return(Line(aControlId)->iCaption);
    }

EXPORT_C CCoeControl* CEikForm::Control(TInt aControlId) const
    {
    return(Line(aControlId)->iControl);
    }

EXPORT_C CCoeControl* CEikForm::ControlOrNull(TInt aControlId) const
	{
	CEikCapCArray* array;
	TInt index=LineIndexFromId(aControlId,array);
	if (index<0)
		return(NULL);
	return((*array)[index]->iControl);
	}

EXPORT_C CEikCaptionedControl* CEikForm::Line(TInt aControlId) const
	{
	CEikCapCArray* array;
	TInt index=LineIndexFromId(aControlId,array);
	if (index<0)
		Panic(EEikFormPanicNoSuchControl);
	return((*array)[index]);
	}

EXPORT_C TInt CEikForm::LineIndexFromId(TInt aControlId,CEikCapCArray*& aArray) const
	{
	aArray=iLines;
	return iLines->LineIndexFromId(aControlId);
	}

EXPORT_C void CEikForm::FocusChanged(TDrawNow aDrawNow)
    {
    if (iCurrentLine>=0)
		{
		if ((*iLines)[iCurrentLine]->IsVisible())	//set the focus only when it is visible
			(*iLines)[iCurrentLine]->SetFocus(IsFocused(),aDrawNow);
		else
			iCurrentLine=-1;
		}
    }

EXPORT_C void CEikForm::Reserved_1()
	{}
EXPORT_C void CEikForm::Reserved_2()
	{}
EXPORT_C void CEikForm::Reserved_3()
	{}
