// EIKSRVSE.CPP
//
// Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.
//

#include "eiksvprv.h"
#include <barsread.h>
#include <e32keys.h>
#include <eikenv.h>
#include <eikcolor.h>

#define KSecretChar '*'
#define KSecretCharAsString "*"

CEikServSecretEditor::CEikServSecretEditor(RWindowGroup& aGroupWin)
    : CEikBorderedControl(TEikBorder(TEikBorder::ESingleGray)),
	iGroupWin(aGroupWin)
	{
	__DECLARE_NAME(_S("CEikServSecretEditor"));
	iSecCharArr.SetLength(iSecCharArr.MaxLength());
	const CFont* font=iCoeEnv->NormalFont();
	iCharWidth=font->TextWidthInPixels(TPtrC((TText*)KSecretCharAsString,1));
	iAscent=font->AscentInPixels(); //HeightInPixels();
	}

void CEikServSecretEditor::ConstructFromResourceL(TResourceReader& aReader)
// construct from resource
	{
	iMaxLen=aReader.ReadUint16();
	__ASSERT_ALWAYS(iMaxLen<=iSecCharArr.MaxLength(), User::Invariant() );
	}

TSize CEikServSecretEditor::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;
	}

TKeyResponse CEikServSecretEditor::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;
	}

void CEikServSecretEditor::GetText(TDes& aText) const
	//
	// Get the actual text typed
	//
 	{
	aText=iSecCharArr.Left(iSecPos);
	}

void CEikServSecretEditor::Reset()
	//
	// Clear the text
	//
	{
	iSecPos=0;
	iSecCharArr.FillZ(); // obliterate any trace of password in memory
	DrawTextNow();
	DisplayCursor();
	}

void CEikServSecretEditor::SetMaxLength(TInt aMaxLength)
	//
	// Set the maximum number of characters for the secret editor
	//
	{
	iMaxLen=aMaxLength;
	__ASSERT_ALWAYS(iMaxLen<=iSecCharArr.MaxLength(), User::Invariant() );
	}

void CEikServSecretEditor::FocusChanged(TDrawNow /*aDrawNow*/)
	//
	// Draw or remove cursor as required depending on whether we have the focus
	//
    {
    if (IsFocused())
        DisplayCursor();
    else 
		iGroupWin.CancelTextCursor();
    }

void CEikServSecretEditor::Draw(const TRect& /*aRect*/) const
	//
	// Draw the whole secret editor
	//
	{
	iBorder.Draw(SystemGc(), Rect());
    DrawText();
	}

void CEikServSecretEditor::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.UseFont(iCoeEnv->NormalFont());
	TSize size=iBorder.SizeDelta();
	gc.DrawText(buf,rect,iAscent+size.iHeight,CGraphicsContext::ELeft,0);
	}

void CEikServSecretEditor::DrawTextNow() const
    {
    ActivateGc();
    DrawText();
    DeactivateGc();
    }

void CEikServSecretEditor::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 !?!
	const CFont* font=iCoeEnv->NormalFont();
    TTextCursor cursor;
    cursor.iType=TTextCursor::ETypeRectangle;
    cursor.iHeight=font->HeightInPixels();
    cursor.iWidth=iCharWidth;
    cursor.iAscent=font->AscentInPixels();
    cursor.iFlags=0;
    cursor.iColor=KRgbWhite;
    iGroupWin.SetTextCursor(*(DrawableWindow()),pos,cursor);
    }

