// EIKSECED.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include <eikseced.h>
#include <barsread.h>
#include <eikenv.h>
#include <eikpanic.h>
#include <e32keys.h>

#include <eikcolor.h>

#define KSecretChar '*'
#define KSecretCharAsString "*"

EXPORT_C CEikSecretEditor::CEikSecretEditor()
    : CEikBorderedControl(TEikBorder(TEikBorder::ESingleGray))
	{
	__DECLARE_NAME(_S("CEikSecretEditor"));
	iSecCharArr.SetLength(iSecCharArr.MaxLength());
	const CFont* font=iCoeEnv->NormalFont();
	iCharWidth=font->TextWidthInPixels(TPtrC((TText*)KSecretCharAsString,1));
	iAscent=font->AscentInPixels(); //HeightInPixels();
	}

EXPORT_C void CEikSecretEditor::ConstructFromResourceL(TResourceReader& aReader)
// construct from resource
	{
	iMaxLen=aReader.ReadUint16();
	__ASSERT_ALWAYS(iMaxLen<=iSecCharArr.MaxLength(), Panic(EEikPanicSecretEditorTooLong) );
	}

EXPORT_C TSize CEikSecretEditor::MinimumSize()
	//
	// returns the minimum size needed to display
	//
	{
	TSize size=iBorder.SizeDelta();
	size.iHeight+=iCoeEnv->NormalFont()->HeightInPixels();
	size.iWidth+=iCharWidth*(iMaxLen+1)+2; // room for cursor at the end + i pixel gap on each side
	return size;
	}

EXPORT_C TKeyResponse CEikSecretEditor::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode /*aType*/)
	//
	// Respond to key presses
	//
	{
	TInt code=aKeyEvent.iCode;
	if ((code==EKeyUpArrow) || (code==EKeyDownArrow))
		return(EKeyWasNotConsumed);
	if (TChar(code).IsPrint() && iSecPos<iMaxLen)
		{
		iSecCharArr[iSecPos]=(TText)code;
		iSecPos++;
        goto update;
		}
	if (code==EKeyBackspace && iSecPos>0)
		{
		iSecPos--;
		iSecCharArr[iSecPos]=0;
    update:
        DrawTextNow();
        DisplayCursor();
		ReportEventL(MCoeControlObserver::EEventStateChanged);
		}
	return EKeyWasConsumed;
	}

EXPORT_C void CEikSecretEditor::GetText(TDes& aText) const
	//
	// Get the actual text typed
	//
 	{
	aText=iSecCharArr.Left(iSecPos);
	}

EXPORT_C void CEikSecretEditor::Reset()
	//
	// Clear the text
	//
	{
	iSecPos=0;
	iSecCharArr.FillZ(); // obliterate any trace of password in memory
	DrawTextNow();
	DisplayCursor();
	}

EXPORT_C void CEikSecretEditor::SetMaxLength(TInt aMaxLength)
	//
	// Set the maximum number of characters for the secret editor
	//
	{
	iMaxLen=aMaxLength;
	__ASSERT_ALWAYS(iMaxLen<=iSecCharArr.MaxLength(), Panic(EEikPanicSecretEditorTooLong) );
	}

EXPORT_C void CEikSecretEditor::FocusChanged(TDrawNow /*aDrawNow*/)
	//
	// Draw or remove cursor as required depending on whether we have the focus
	//
    {
    if (IsFocused())
        DisplayCursor();
    else 
		iEikonEnv->HideCursor(this);
    }

EXPORT_C void CEikSecretEditor::Draw(const TRect& /*aRect*/) const
	//
	// Draw the whole secret editor
	//
	{
	iBorder.Draw(SystemGc(), Rect());
    DrawText();
	}

void CEikSecretEditor::DrawText() const
	//
	// Draw everything inside the border flicker free
	//
	{
	CWindowGc& gc=SystemGc();
	TSecEdBuf buf;
    buf.Fill(KSecretChar,iSecPos);
	TRect rect=iBorder.InnerRect(Rect());
	rect.iTl.iX++; //leave one pixel gap between the border and text
	gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
	gc.SetBrushColor(iEikonEnv->ControlColor(EEikColorWindowBackground,*this)); // KEikSecretEditorBackgroundColor
	gc.SetPenColor(iEikonEnv->ControlColor(EEikColorWindowText,*this));
    gc.UseFont(iCoeEnv->NormalFont());
	TSize size=iBorder.SizeDelta();
	gc.DrawText(buf,rect,iAscent+size.iHeight,CGraphicsContext::ELeft,0);
	}

void CEikSecretEditor::DrawTextNow() const
    {
    ActivateGc();
    DrawText();
    DeactivateGc();
    }

void CEikSecretEditor::DisplayCursor()
	//
	// Draw the cursor at the appropriate position
	//
    {
    if (!IsFocused())
        return;
    TPoint pos=Position();
    TMargins margins=iBorder.Margins();
    pos.iX+=margins.iLeft+iSecPos*iCharWidth+1;
    pos.iY+=iAscent+2;	//subtract one for one pixel gap on all sides ??? what !?!
    iEikonEnv->DrawCursor(this,pos,iCharWidth);
    }

EXPORT_C void CEikSecretEditor::Reserved_1()
	{}
EXPORT_C void CEikSecretEditor::Reserved_2()
	{}
