import java.applet.Applet;
import java.awt.*;

/**
 * Classe que comporta o metodo init e o m&eacutetodo main.
 */
public class Simulador2 extends Applet {
        Panel painel;
        Interface_conta interface_conta;
        TextField textfield;

        /**
         * M&eacutetodo invocado automaticamente quando um Applet &eacute executado,
         * ou se chamamos o m&eacutetodo diretamente.
         */
        public void init() {
                setLayout(new FlowLayout());
                painel = new Panel();
                textfield = new TextField(12);
                painel.setLayout(new FlowLayout());
                painel.add(new Label("O numero da conta:"));
                painel.add(textfield);
                painel.add(new Button("OK"));
                add(painel);
        }

        public boolean action(Event evt, Object arg) {
                Object alvo = evt.target;
                String texto = textfield.getText();
                long numero = Long.valueOf(texto).longValue();

                if (alvo instanceof Button) {
                        remove(painel);
                        interface_conta = new Interface_conta(numero);
                        interface_conta.mostra(this);
                        return true;
                } else return false;
        }
                

        /**
         * M&eacutetodo invocado quando uma aplicac&atildeo stand-alone &eacute executada.
         */
        public static void main(String args[]) {
                Frame f = new Frame("Simulador de um objeto Conta Bancaria");
                Simulador2 simulador2 = new Simulador2();
                simulador2.init();
                f.add("Center", simulador2);
                f.move(100, 450);
                f.pack();
                f.resize(600, 600);
                f.show();
        }
}


/**
 * Define um agrupamento de contas banc&aacutearias
 */
class Conta {

        private double saldo;
        private long numero;

        /**
         * Retorna o numero de uma conta
         */
        public long num_conta() {
                return numero;
        }

        /**
         * Retorna o saldo de uma conta
         */
        public double saldo_conta() {
                return saldo;
        }

        /**
         * Credita uma determinada quantia
         * @param val               quantia a ser creditada
         */
        public void credito(double val) {
                saldo = saldo + val ;
        }

        /**
         * Debita uma determinada quantia
         * @param val               quantia a ser debitada
         */
        public void debito(double val) {
                saldo = saldo - val;
        }

        /**
         * Retorna uma string contendo o numero e o saldo de uma conta
         */
        public String print_saldo() {
                String texto;
                texto = "Conta: " + numero + "     Saldo: R$ " + saldo;
                return texto;
        }

        /**
         * Inicializa uma conta
         * @param num               numero da conta
         * @param val               saldo da conta
         */
        public Conta(double val, long num) {
                saldo = val;
                numero = num;
        }

        /**
         * Inicializa uma conta
         * @param val               saldo da conta
         */
        public Conta(double val) {
                saldo = val;
        }
}

/**
 * Define uma interface grafica para um objeto conta bancaria
 */
class Interface_conta extends Panel
{

        Button credito, debito, extrato;
        Conta conta;
        Janela_transacao janela_transacao;
        Janela_extrato janela_extrato;

        /**
         * Retorna um objeto conta
         */
        public Conta getconta() {
                return conta;
        }

        public void paint(Graphics g) {
                
                int posx;
                int posy;
                int decMaior;           //decremento maior
                int decMenor;           //decremento menor
                int incremento;  
                int margem;
                int margem1;
                int margem2;
                int margem3;
                int margembh;           //margem horizontal dos botoes credito e debito
                int margembv;           //margem vertical do botao print_saldo
                int wnumero, wsaldo;    //largura do numero e do saldo da conta
                String snumero, ssaldo; //numero e saldo convertidos para String


                //inicializacoes
                posx = 300;
                posy = 300;
                g.setFont(new Font("Helvetica", Font.PLAIN, 10));
                snumero = Long.toString(conta.num_conta());
                ssaldo = Double.toString(conta.saldo_conta());
                wnumero = g.getFontMetrics().stringWidth(snumero); 
                wsaldo =  g.getFontMetrics().stringWidth(ssaldo);
                incremento = Math.max(wnumero, wsaldo);
                decMenor = incremento/2 + 30;
                decMaior = 2 * decMenor + 30;
                margembh = (decMaior-3 - decMenor - 50)/2;
                margembv = (decMaior-3 - decMenor -25)/2;

                //posiciona os botoes.
                credito.reshape(posx-decMaior+3+margembh, posy-10, 50, 25);
                debito.reshape(posx+decMenor+margembh, posy-10, 50, 25);
                extrato.reshape(posx-30, posy-decMaior+3+margembv, 60, 25);

                //permita que a partir de agora ponto dado seja a origem do grafico
                g.translate(posx, posy);

                //circulo cinza com a borda preta
                g.setColor(Color.black);
                g.fillOval(-decMaior, -decMaior, 2*decMaior, 2*decMaior); 
                g.setColor(Color.gray);
                g.fillOval(-decMaior+3,-decMaior+3, 2*(decMaior-3), 2*(decMaior-3));

                // circulo branco com a borda azul
                g.setColor(Color.blue);
                g.fillOval(-decMenor, -decMenor, 2*decMenor, 2*decMenor);
                g.setColor(Color.white);
                g.fillOval(-decMenor+3, -decMenor+3, 2*(decMenor-3), 2*(decMenor-3));

                //traco que divide circulo interno ao meio
                g.setColor(Color.blue);
                g.fillRect(-decMenor+3, -2, 2*(decMenor-3), 4);

                //poe no circulo interno as palavras Numero e Saldo
                g.setColor(Color.black);

                // poe o numero da conta no applet centralizado
                margem = (2*decMenor - wnumero)/2;
                g.drawString(snumero, -(decMenor-margem), -decMenor/2 + 10);

                // poe a palavra Numero no applet centralizada
                margem1 = (2*decMenor - g.getFontMetrics().stringWidth("Numero"))/2;
                g.drawString("Numero", -(decMenor-margem1), -decMenor/2);

                //poe o saldo da conta no applet centralizado
                margem2 = (2*decMenor - wsaldo)/2;
                g.drawString(ssaldo, -(decMenor-margem2), decMenor/2 + 2);

                //poe a palavra Saldo no Applet centralizada
                margem3 = (2*decMenor - g.getFontMetrics().stringWidth("Saldo"))/2;
                g.drawString("Saldo", -(decMenor-margem3), decMenor/2 - 10 + 2);
        }        

        /**
         * Coloca a interface_conta no applet
         */
        public void mostra(Applet tela) {
                repaint();
                tela.add(this);
                validate();
        }

        /**
         * Verifica se algum dos botoes(credito, debito ou printsaldo) foi pressionado
         */
        public boolean action(Event evt, Object arg) {
                Object alvo = evt.target;
                
                if (alvo == credito){
                        janela_transacao  = new Janela_transacao("credito", this);
                        return true;
                }else if (alvo == debito) {
                        janela_transacao = new Janela_transacao("debito", this);
                        return true;    
                }else if (alvo == extrato) {
                        janela_extrato = new Janela_extrato("print_saldo", this);
                        return true;
                }else return false;
        }

        /**
         * Inicializa uma conta e os componentes
         * de sua interface grafica(adicionando-os em interface_conta)
         * @param valor               o numero da conta
         */
        public Interface_conta(long numero) {
                conta = new Conta(0, numero);
                setLayout(new BorderLayout());
                resize(600,600);
                credito = new Button ("Credito");
                debito = new Button ("Debito");
                extrato = new Button ("Printsaldo");
                add(credito);
                add(debito);
                add(extrato);

        }
}

/**
 * Define uma janela de transacao(credito e debito)
 */
class Janela_transacao extends Frame
{   
   TextField textfield;
   Button confirma, cancela;
   Conta conta;
   Interface_conta interface_conta;

   /**
    * Adiciona os componentes no objeto janela
    */
   public void adiciona()
   {
        add(new Label("Digite a quantia:")); 
        add(textfield);
        add(confirma);
        add(cancela);
   }            

   /**
    * Verifica se o botao confirma ou cancela foi pressionado
    */
   public boolean action(Event e, Object arg)
   {
        Object alvo = e.target;
        if (alvo == confirma)
        {
                confirma();
                hide();
                interface_conta.repaint();
                return true;
        }
        if (alvo == cancela)
	{
		hide();
		return true;
	}
        return false;                      
   }
   /**
    * Confirma um saque ou deposito dependendo do titulo da janela
    */
   void confirma()
   {
        String texto = textfield.getText();
        long valor = Long.valueOf(texto).longValue();
         
        if ("credito".equals(getTitle()))
        {       
           conta.credito(valor);
        }
        else
        {
           conta.debito(valor);
        }
   }

   /**
    * Inicializa uma janela de transacao e chama o metodo adiciona
    * @param titulo                   titulo da janela
    * @param interface_conta          objeto que tem como atributo uma conta
    */
   public Janela_transacao(String titulo, Interface_conta interface_conta)
   {
        super(titulo);
        this.interface_conta = interface_conta;
        this.conta = interface_conta.getconta();
        setLayout(new FlowLayout(FlowLayout.CENTER, 50, 20));

        textfield = new TextField(20);
        confirma = new Button("Confirma");
        cancela = new Button("Cancela");

        adiciona();
        pack();
        resize(300,200);
        show();
   }
}

/**
 * Define uma janela que exibe o extrato de uma conta
 */
class Janela_extrato extends Frame
{
        TextField textfield;
        Button botao;
        Conta conta;
        
        int H_SIZE = 250;
        int V_SIZE = 150;

        /**
         * Inicializa uma janela de extrato e adiciona seus componentes nela
         * @param titulo                    titulo da janela
         * @param interface_conta           objeto que tem como atributo uma conta
         */
        public Janela_extrato(String titulo, Interface_conta interface_conta)
        {
                super(titulo);
                this.conta = interface_conta.getconta();
        
                setLayout(new BorderLayout());
        
                add("North",new Label(conta.print_saldo()));
                botao = new Button("OK");
                add(botao);
                botao.reshape((H_SIZE-50)/2,V_SIZE/2,50,20);
        
                pack();
                resize(H_SIZE, V_SIZE);
                show();   
        }

        /**
         * Verifica se o botao "OK" foi pressionado
         */
        public boolean action(Event e, Object arg)
        {
                Object target = e.target;
                if (target == botao){
                        hide();
                        return true;
                }
                
                return false;
        }
                
}





