<repo_name>tales42/AS_TP2<file_sep>/src/Exception/ApostadorRegistadoException.java
package Exception;

/**
 * Created by luismp on 11/11/2018.
 */
public class ApostadorRegistadoException extends Exception {
    String email;

    public ApostadorRegistadoException(String email){
        this.email = email;
    }

    public String getEmail(){
        return this.email;
    }
}
<file_sep>/src/Exception/SaldoInsuficienteException.java
package Exception;

/**
 * Created by luismp on 11/11/2018.
 */
public class SaldoInsuficienteException extends Exception {

    double quantia;

    public SaldoInsuficienteException(double quantia){
        this.quantia = quantia;
    }

    public double getQuantia(){
        return this.quantia;
    }


}
<file_sep>/src/GUI/GUIMainPage.java
package GUI;

import Business.AdministradorDeEventos;
import Business.Apostador;
import Business.Utilizador;
import Exception.*;

/**
 * Created by luismp on 20/12/2018.
 */
public class GUIMainPage extends GUI {


    /**
     * Método que imprime no ecrã o menu principal
     */
    private static void showMainPage() {
        System.out.println("----- BET ESS -----");
        if (getAtual() != null) {
            System.out.println("Utilizador: " + getAtual().getNome());
        }
        System.out.println("1 - Efetuar Registo");
        System.out.println("2 - Iniciar Sessão");
        System.out.println("3 - Consultar Eventos");
        System.out.println("0 - Sair");
        System.out.println("-------------------");
    }

    /**
     * Método que mostra o menu principal e mantém o handler a correr
     */
    protected static void mainPageForm() {
        showMainPage();
        boolean handler = true;
        while (handler) {
            handler = mainPageHandler();
        }

    }

    /**
     * Handler do menu principal que recebe e trata os inputs do utilizador.
     * Retorna false quando o utilizador pretende sair do programa, parando o ciclo e a execução do programa
     * @return Booleano
     */
    private static boolean mainPageHandler() {
        String option = readLine();
        if (option.equals("1")) {
            registerForm();
            showMainPage();
        } else if (option.equals("2")) {
            showLoginForm();
            showMainPage();
        } else if (option.equals("3")) {
            GUIApostador.showEvents();
            showMainPage();
        } else if (option.equals("0")) {
            terminarSessao();
            saveFile();
            return false;
        } else {
            System.out.println("Input não reconhecido.");
        }
        return true;
    }

    /**
     * Método que imprime no ecrã o formulário de autenticação
     */
    private static void showLoginForm() {
        System.out.println("---- Iniciar Sessão ----");
        System.out.println("Email:");
        String email = readLine();
        System.out.println("Password:");
        String password = readLine();
        tryLogIn(email, password);

    }

    /**
     * Método que tenta autenticar um utilizado no sistema
     * @param email
     * @param password
     */
    private static void tryLogIn(String email, String password) {
        try {
            iniciarSessao(email, password);
            System.out.println("Sessão iniciada com sucesso.");
            confirmarContinuar();
            loggedInHandler();
        } catch (PasswordIncorretaException e) {
            System.out.println("Password Incorreta.");
            confirmarContinuar();
        } catch (UtilizadorInexistenteException e) {
            System.out.println("Utilizador Inexistente.");
            confirmarContinuar();
        }
    }

    /**
     * Método que imprime no ecrã o formulário de registo
     */
    private static void registerForm() {
        System.out.println("---- Efetuar Registo ----");
        System.out.println("Insira o seu email");
        String email = readLine();
        System.out.println("Insira a sua password");
        String password = readLine();
        System.out.println("Insira o seu nome");
        String nome = readLine();
        tryRegistarApostador(email, password, nome);
    }

    /**
     * Método que tenta registar um novo Apostador no sistema
     * @param email
     * @param password
     * @param nome
     */
    private static void tryRegistarApostador(String email, String password, String nome) {
        try {
            registarApostador(email, password, nome);
            System.out.println("Utilizador registado com sucesso.");
            confirmarContinuar();
        } catch (ApostadorRegistadoException e) {
            System.out.println("Utilizador já registado.");
            confirmarContinuar();
        }
    }

    /**
     * Método que imprime a página após a autenticação do utilizador, de acordo com qual o tipo de Utilizador autenticado
     * @see Utilizador
     */
    protected static void loggedInScene() {
        Utilizador atual = getAtual();
        if (atual instanceof AdministradorDeEventos) {
            adminLoggedInScene();
        } else if (atual instanceof Apostador) {
            apostadorLoggedInScene((Apostador) atual);
        }
    }

    /**
     * Método que imprime a página após autenticação de um administrador
     * @see AdministradorDeEventos
     */
    private static void adminLoggedInScene() {
        System.out.println("---- Administrador -----");
        System.out.println("1 - Registar Evento");
        System.out.println("2 - Consultar Eventos");
        System.out.println("3 - Fechar Evento");
        System.out.println("0 - Sair");
        System.out.println("-------------------------");
    }

    /**
     * Método que imprime a página após autenticação de um apostador, e apresenta os seus dados no ecrã
     * @param atual
     * @see Apostador
     */
    private static void apostadorLoggedInScene(Apostador atual) {
        System.out.println("---- Apostador -----");
        System.out.println("Nome: " + atual.getNome());
        System.out.println("Saldo: " + atual.getSaldo());
        System.out.println("Cartão: " + atual.getCartaoAssociado());
        System.out.println("--------------------");
        System.out.println("1 - Consultar Notificações ");
        System.out.println("2 - Gerir Saldo ");
        System.out.println("3 - Consultar Resultados ");
        System.out.println("4 - Consultar Eventos");
        System.out.println("5 - Consultar Apostas Realizadas");
        System.out.println("6 - Registar Aposta");
        System.out.println("0 - Sair");
        System.out.println("--------------------");
    }

    /**
     * Método que recebe e trata dos inputs da página após o login
     */
    private static void loggedInHandler() {
        loggedInScene();
        Utilizador atual = getAtual();
        boolean isLoggedIn = true;
        if (atual instanceof AdministradorDeEventos) {
            while (isLoggedIn) {
                isLoggedIn = GUIEvento.adminLoggedInHandler();
            }
        } else if (atual instanceof Apostador) {
            while (isLoggedIn) {
                isLoggedIn = GUIApostador.apostadorLoggedInHandler();
            }
        }
    }
}
<file_sep>/src/Business/BetESS.java
package Business;

import java.io.Serializable;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import Exception.ApostadorRegistadoException;
import Exception.PasswordIncorretaException;
import Exception.UtilizadorInexistenteException;

/**
 * Created by luismp on 11/11/2018.
 */
public class BetESS implements Serializable {

    private Map<Integer,Utilizador> utilizadores;
    private Map<Integer, Desporto> desportos;
    private Map<Integer,Equipa> equipas;
    private Map<Integer,Evento> eventos;
    private Utilizador atual;


    /**
     * Construtor Vazio de um Objeto BetESS
     */
    public BetESS(){
        this.utilizadores = new HashMap<>();
        this.desportos = new HashMap<>();
        this.equipas = new HashMap<>();
        this.eventos = new HashMap<>();
        this.atual = null;
    }

    /**
     * Método que define quais os utilizadores de um sistema.
     * Só é usado em casos de teste para povoar o sistema.
     * @param utilizadores
     */
    public void setUtilizadores(Map<Integer, Utilizador> utilizadores) {
        this.utilizadores = utilizadores;
    }


    /**
     * Setter do Utilizador atual.
     * @param atual
     */
    public void setAtual(Utilizador atual){
        this.atual = atual;
    }

    /**
     * Método que regista um novo Apostador no Sistema.
     * Lança uma exceção caso o email utilizado já esteja registado no sistema
     * @param email
     * @param password
     * @param nome
     * @throws ApostadorRegistadoException
     */
    public void registarApostador(String email, String password, String nome) throws ApostadorRegistadoException {
        for(Utilizador utilizador : utilizadores.values()){
            if(utilizador.getEmail().equals(email)) throw new ApostadorRegistadoException(email);
        }
        Apostador apostador = new Apostador(utilizadores.size()+1,email,password,nome);
        utilizadores.put(apostador.getIdUtilizador(),apostador);
    }

    /**
     * Método que tenta autentica um utilizador no sistema.
     * Lança uma exceção caso a o utilizador não exista no sistema, ou caso a password esteja errada.
     * @param email
     * @param password
     * @throws PasswordIncorretaException
     * @throws UtilizadorInexistenteException
     */
    public void iniciarSessao(String email, String password) throws PasswordIncorretaException, UtilizadorInexistenteException {
        Utilizador atual = getUtilizador(email);
        if((getUtilizador(email).getIdUtilizador() == 0)) throw new UtilizadorInexistenteException();
        if(!atual.getPassword().equals(password)) throw new PasswordIncorretaException();
        else setAtual(atual);
    }

    /**
     * Método que termina a sessão do utilizador atual.
     */
    public void terminarSessao(){
        atual = null;
    }

    /**
     * Método que determina qual o utilizado que possui um email passado como parâmetro
     * @param email
     * @return Utilizador
     */
    public Utilizador getUtilizador(String email){
        Utilizador ret = new Utilizador();
        for(Utilizador utilizador : utilizadores.values()){
            if(utilizador.getEmail().equals(email)){
                ret = utilizador;
                break;
            }
        }
        return ret;
    }

    /**
     * Getter dos Eventos do Sistema
     * @return Eventos
     */
    public Map<Integer,Evento> getEventos(){
        return eventos;
    }

    /**
     * Getter dos Utilizadores do sistema
     * @return Utilizadores
     */
    public Map<Integer,Utilizador> getUtilizadores(){
        return utilizadores;
    }

    /**
     * Getter do Utilizador atual
     * @return Utilizador Atual
     */
    public Utilizador getAtual(){
        return atual;
    }


    /**
     * Getter dos Desportos do sistema.
     * @return Desportos
     */
    public Map<Integer,Desporto> getDesportos(){
        return desportos;
    }

    /**
     * Getter das Equipas do Sistema.
     * @return Equipas
     */
    public Map<Integer,Equipa> getEquipas(){
        return equipas;
    }

    /**
     * Método que devolve uma coleção com os eventos que se encontram no estado aberto.
     * @return Eventos Abertos
     */
    public Map<Integer, Evento> getEventosAbertos(){
        Map<Integer,Evento> eventosAbertos = new HashMap<>();
        for(Evento e: eventos.values()){
            if(e.getEstado() == 'A') eventosAbertos.put(e.getIdEvento(),e);
        }
        return eventosAbertos;
    }

    /**
     * Método que regista um novo Evento no sistema.
     * @param idDesporto
     * @param idEquipa1
     * @param idEquipa2
     * @param data
     * @param hora
     * @param odds
     * @param localizacao
     */
    public void registarEvento(int  idDesporto, int idEquipa1, int idEquipa2, String data, String hora, List<Double> odds, String localizacao){
        Desporto desp = desportos.get(idDesporto);
        Equipa eq1 = equipas.get(idEquipa1);
        Equipa eq2 = equipas.get(idEquipa2);


        DateTimeFormatter format = DateTimeFormatter.ofPattern("d-M-y");
        LocalDate date = LocalDate.parse(data,format);

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("H:m");
        LocalTime horaComeco = LocalTime.parse(hora,dtf);

        Resultado vitoriaEquipa1 = new Resultado("Vitoria Equipa 1", (odds.get(0)));
        Resultado empate = new Resultado("Empate",(odds.get(1)));
        Resultado vitoriaEquipa2 = new Resultado("Vitoria Equipa 2",(odds.get(2)));
        List<Resultado> resultados = new ArrayList<>();
        resultados.add(vitoriaEquipa1);
        resultados.add(empate);
        resultados.add(vitoriaEquipa2);

        Duration duracao = Duration.ofMinutes(90);
        DetalhesEvento detalhesEvento = new DetalhesEvento(date,horaComeco,duracao,localizacao,eq1,eq2,desp);
        Evento evento = new Evento(eventos.size()+1, resultados, detalhesEvento);

        eventos.put(evento.getIdEvento(),evento);

    }

    /**
     * Método que verifica se um evento está aberto.
     * @param idEvento
     * @return Boolean
     */
    public boolean isEventoAberto(int idEvento){
        return eventos.keySet().contains(idEvento);
    }

    /**
     * Método que altera o estado de um evento
     * @param idEvento
     */
    public void alterarEstado(int idEvento){
        eventos.get(idEvento).alterarEstado(this);
    }

    /**
     * Método que retorna o evento associado a um identificador
     * @param idEvento
     * @return Evento
     */
    public Evento getEvento(int idEvento){
        return eventos.get(idEvento);
    }

    /**
     * Método que retorna a designação da equipa associada a um identificador
     * @param idEquipa
     * @return Designação
     */
    public String getDesignacaoEquipa(int idEquipa){
        return equipas.get(idEquipa).getDesignacao();
    }

    /**
     * Método utilizado para povoar o sistema, caso não exista nenhum ficheiro de dados disponível.
     */
    public void initializeSystem(){
        Utilizador admin = new AdministradorDeEventos(getUtilizadores().size()+1,"admin","betess","Admin");
        getUtilizadores().put(admin.getIdUtilizador(),admin);
        Desporto futebol = new Desporto(1,"Futebol");
        desportos.put(futebol.getIdDesporto(),futebol);
        Desporto basquetebol = new Desporto(2,"Basquetebol");
        desportos.put(basquetebol.getIdDesporto(),basquetebol);
        Equipa slb = new Equipa(1,"Sport Lisboa e Benfica");
        equipas.put(slb.getIdEquipa(),slb);
        Equipa fcp = new Equipa(2, "Futebol Clube do Porto");
        equipas.put(fcp.getIdEquipa(),fcp);
    }
}
<file_sep>/src/Business/Apostador.java
package Business;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import Exception.SaldoInsuficienteException;

/**
 * Created by luismp on 10/11/2018.
 */
public class Apostador extends Utilizador {
    private String cartaoAssociado;
    private double saldo;
    private Map<Integer,Aposta> apostas;
    private List<Notificacao> notificacoes;


    /**
     * Construtor vazio
     */
    public Apostador(){
        cartaoAssociado = "";
        saldo=0;
        apostas = new HashMap<>();
        notificacoes = new ArrayList<>();
    }

    /**
     * Construtor parametrizado
     * @param idUtilizador
     * @param email
     * @param password
     * @param nome
     */
    public Apostador(int idUtilizador, String email, String password, String nome){
        super(idUtilizador,email,password,nome);
        this.setCartaoAssociado(cartaoAssociado);
        this.setSaldo(saldo);
        this.setApostas(new HashMap<>());
        this.setNotificacoes(new ArrayList<>());
    }


    /**
     * Getter cartão associado
     * @return Cartão associado
     */
    public String getCartaoAssociado() {
        return cartaoAssociado;
    }

    /**
     * Setter cartão associado
     * @param cartaoAssociado
     */
    public void setCartaoAssociado(String cartaoAssociado) {
        this.cartaoAssociado = cartaoAssociado;
    }

    /**
     * Getter Saldo
     * @return Saldo
     */
    public double getSaldo() {
        return saldo;
    }

    /**
     * Setter saldo
     * @param saldo
     */
    public void setSaldo(double saldo) {
        this.saldo = saldo;
    }

    /**
     * Getter apostas
     * @return Apostas
     */
    public Map<Integer, Aposta> getApostas() {
        return apostas;
    }

    /**
     * Setter apostas
     * @param apostas
     */
    public void setApostas(Map<Integer, Aposta> apostas) {
        this.apostas = apostas;
    }

    /**
     * Getter notificações
     * @return Notificações
     */
    public List<Notificacao> getNotificacoes() {
        return notificacoes;
    }

    /**
     * Setter notificações
     * @param notificacoes
     */
    public void setNotificacoes(List<Notificacao> notificacoes) {
        this.notificacoes = notificacoes;
    }

    /**
     * Clone
     * @return Apostador
     */
    public Apostador clone(){
        int idUtilizador = this.getIdUtilizador();
        String email = this.getEmail();
        String password = this.<PASSWORD>();
        String nome = this.getNome();
        return new Apostador(idUtilizador,email,password,nome);
    }

    /**
     * Equals
     * @param object
     * @return Boolean
     */
    public boolean equals(Object object){
        if(object == this) return true;

        if(object==null || object.getClass() != getClass()) return false;

        Apostador apostador = (Apostador) object;

        return apostador.getIdUtilizador() == getIdUtilizador();
    }


    /**
     * toString
     * @return String
     */
    public String toString(){
        StringBuilder string = new StringBuilder();
        string
            .append("----Business.Apostador----\nID : ")
            .append(this.getIdUtilizador())
            .append("\nEmail : ")
            .append(this.getEmail())
            .append("\nNome : ")
            .append(this.getNome())
            .append("\nCartão Associado : ")
            .append(this.getCartaoAssociado())
            .append("\nSaldo : ")
            .append(this.getSaldo())
            .append("€\n------------------\n");
        return string.toString();
    }


    /**
     * Método que deposita uma quantia em ESSCoins na conta de um Apostador
     * @param quantia
     */
    public void depositar(double quantia){
        double novoSaldo = getSaldo() + quantia;
        setSaldo(novoSaldo);
    }

    /**
     * Método que levanta uma quantia em ESSCoins da conta de um Apostador
     * Lança uma exceção caso não possua saldo suficiente
     * @param quantia
     * @throws SaldoInsuficienteException
     */
    public void levantar(double quantia) throws SaldoInsuficienteException {
        double novoSaldo = this.getSaldo() - quantia;
        if(novoSaldo < 0) throw new SaldoInsuficienteException(novoSaldo);
        else setSaldo(novoSaldo);
    }

    /**
     * Método que regista uma nova Aposta
     * Lança uma exceção caso o Apostador não possua saldo suficiente
     * @param evento
     * @param resultado
     * @param quantia
     * @throws SaldoInsuficienteException
     */
    public void registarAposta( Evento evento, Resultado resultado, double quantia) throws SaldoInsuficienteException{
        levantar(quantia);
        Aposta aposta = new Aposta();
        int idAposta = apostas.size()+1;
        aposta.setIdAposta(idAposta);
        aposta.setResultado(resultado);
        aposta.setQuantia(quantia);
        aposta.setGanhosPossiveis(aposta.calcularGanhos());
        apostas.put(idAposta,aposta);
        evento.getApostas().put(getIdUtilizador(),aposta);
    }

    /**
     * Método que adiciona uma nova notificação no Apostador
     * @param notificacao
     */
    public void addNotificacao(Notificacao notificacao){
        notificacoes.add(notificacao);
    }

}
<file_sep>/test/Business/ApostaTest.java
package Business;

import static org.junit.Assert.*;

/**
 * Created by luismp on 21/12/2018.
 */
public class ApostaTest {
    @org.junit.Test
    public void calcularGanhos() throws Exception {

        Resultado resultadoFinal = new Resultado("Vitoria",2.5);
        Aposta aposta = new Aposta(1,100,resultadoFinal);
        assertEquals(aposta.calcularGanhos(), 100*2.5,0.000001);
    }


}<file_sep>/test/Business/EventoTest.java
package Business;

import org.junit.Test;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static org.junit.Assert.*;

/**
 * Created by luismp on 21/12/2018.
 */
public class EventoTest {
    @Test
    public void alterarEstado() throws Exception {
        Resultado vitoria1 = new Resultado("Vitória da Equipa 1", 2);
        Resultado empate = new Resultado("Empate", 1);
        Resultado vitoria2 = new Resultado("Vitória da Equipa 2", 3);

        List<Resultado> resultadoList = new ArrayList<>();
        resultadoList.add(vitoria1);
        resultadoList.add(empate);
        resultadoList.add(vitoria2);

        DetalhesEvento detalhesEvento = new DetalhesEvento(LocalDate.now(),LocalTime.now(),Duration.ofMinutes(90),"estádio", new Equipa(1,"SLB"), new Equipa(2,"FCP"),new Desporto(1,"Futebol") );
        Evento evento = new Evento(1,resultadoList,detalhesEvento);


        Apostador apostador1 = new Apostador(1,"Tales","Tales","Tales");
        apostador1.depositar(100);
        apostador1.setIdUtilizador(10);
        apostador1.registarAposta(evento,vitoria1,50);

        Apostador apostador2 = new Apostador(2,"Bomber","Bomber","Bomber");
        apostador2.depositar(100);
        apostador2.setIdUtilizador(20);
        apostador2.registarAposta(evento,empate,50);

        Apostador apostador3 = new Apostador(3,"Gigo","Gigo","Gigo");
        apostador3.depositar(100);
        apostador3.setIdUtilizador(30);
        apostador3.registarAposta(evento,vitoria2,50);

        BetESS bet = new BetESS();
        HashMap<Integer, Utilizador> utilizadorHashMap = new HashMap<>();
        utilizadorHashMap.put(apostador1.getIdUtilizador(),apostador1);
        utilizadorHashMap.put(apostador2.getIdUtilizador(),apostador2);
        utilizadorHashMap.put(apostador3.getIdUtilizador(),apostador3);
        bet.setUtilizadores(utilizadorHashMap);

        evento.alterarEstado(bet);

        if(evento.getResultadoFinal().getDesignacao().equals(vitoria1.getDesignacao())){
            assertEquals(150,apostador1.getSaldo(),0.0000001);
        }
        else if(evento.getResultadoFinal().getDesignacao().equals(empate.getDesignacao())){
            assertEquals(100,apostador2.getSaldo(),0.0000001);
        }
        else if(evento.getResultadoFinal().getDesignacao().equals(vitoria2.getDesignacao())){
            assertEquals(200,apostador3.getSaldo(),0.0000001);
        }

        assertEquals(1,apostador1.getNotificacoes().size(),0.0000001);
        assertEquals(1,apostador2.getNotificacoes().size(),0.0000001);
        assertEquals(1,apostador3.getNotificacoes().size(),0.0000001);


    }


}<file_sep>/src/Business/Notificacao.java
package Business;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * Created by luismp on 10/11/2018.
 */
public class Notificacao implements Serializable {
    private LocalDateTime data;
    private String texto;

    /**
     * Construtor Vazio de uma Notificação
     */
    public Notificacao(){
        this.data = LocalDateTime.now();
        this.texto="";
    }

    /**
     * Getter da Data de uma Notificação
     * @return Data
     */
    public LocalDateTime getData() {
        return data;
    }

    /**
     * Getter do Texto de uma Notificação
     * @return Texto
     */
    public String getTexto() {
        return texto;
    }

    /**
     * Setter do texto de uma Notificação
     * @param texto
     */
    public void setTexto(String texto) {
        this.texto = texto;
    }


    /**
     * Método clone()
     * @return
     */
    public Notificacao clone(){
        Notificacao notificacao = new Notificacao();
        notificacao.setTexto(texto);
        return notificacao;
    }

    /**
     * toString
     * @return String
     */
    public String toString(){
        StringBuilder string = new StringBuilder();
        string
                .append("----Notificação----\nTimestamp : ")
                .append(this.getData())
                .append("\n")
                .append(this.getTexto())
                .append("\n-------------------\n");
        return string.toString();
    }
}
<file_sep>/src/GUI/GUISaldo.java
package GUI;

import Business.Apostador;
import Business.BetESS;
import Exception.*;

import java.util.Scanner;
import java.util.regex.Pattern;

/**
 * Created by luismp on 20/12/2018.
 */
public class GUISaldo extends GUI {

    /**
     * Método que imprime no ecrã o menu de gestão do Saldo de um Apostador
     */
    protected static void gerirSaldoScene() {
        System.out.println("--- Gerir Saldo ---");
        System.out.println("1 - Associar Cartão");
        System.out.println("2 - Depositar Dinheiro");
        System.out.println("3 - Levantar Dinheiro");
        System.out.println("0 - Sair");
        System.out.println("-------------------");
    }

    /**
     * Método que recebe e trata os inputs relativos ao menu de gestão de saldo
     */
    protected static void gerirSaldoHandler() {
        while (true) {
            String opcao = readLine();
            if (opcao.equals("1")) {
                associarCartao();
                confirmarContinuar();
                gerirSaldoScene();
            } else if (opcao.equals("2")) {
                depositarDinheiro();
                confirmarContinuar();
                gerirSaldoScene();
            } else if (opcao.equals("3")) {
                levantarDinheiro();
                confirmarContinuar();
                gerirSaldoScene();
            } else if (opcao.equals("0")) {
                break;
            } else {
                System.out.println("Input não reconhecido");
                confirmarContinuar();
                gerirSaldoScene();
            }
        }
    }

    /**
     * Método que permite um Apostador associar um cartão ao sistema
     */
    private static void associarCartao() {
        Apostador atual = (Apostador) getAtual();
        System.out.println("Insira o número do cartão, do tipo dddd-dddd-dddd-dddd");
        try {
            String novoCartao = validarCartao();
            atual.setCartaoAssociado(novoCartao);
        } catch (Exception e) {
            System.out.println("Cartão inválido");
            confirmarContinuar();
            return;
        }
    }

    /**
     * Método que valida o cartão inserido baseado na forma
     * @return Cartão
     */
    private static String validarCartao() {
        Scanner scanner = new Scanner(System.in);
        Pattern mb = Pattern.compile("[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}");
        return scanner.next(mb);
    }

    /**
     * Método que permite ao Apostador depositar dinheiro no sistema
     */
    private static void depositarDinheiro() {
        Apostador atual = (Apostador) getAtual();
        System.out.println("Qual a quantia que quer depositar?");
        String quantia = readLine();
        if (isDouble(quantia)) {
            double qt = Double.parseDouble(quantia);
            atual.depositar(qt);
            confirmarContinuar();
        } else {
            System.out.println("Valor inválido");
            confirmarContinuar();
            return;
        }
    }

    /**
     * Método que permite ao Apostador levantar dinheiro do sistema
     */
    private static void levantarDinheiro() {
        Apostador atual = (Apostador) getAtual();
        System.out.println("Qual a quantia que quer levantar?");
        String quantia = readLine();
        if (isDouble(quantia)) {
            double qt = Double.parseDouble(quantia);
            try {
                atual.levantar(qt);
                confirmarContinuar();
            } catch (SaldoInsuficienteException e) {
                System.out.println("Impossível levantar essa quantia");
                confirmarContinuar();
                return;
            }
        }
    }

}
<file_sep>/src/GUI/GUIApostador.java
package GUI;

import Business.Aposta;
import Business.Apostador;
import Business.Evento;
import Business.Notificacao;
import Business.Resultado;
import Exception.SaldoInsuficienteException;

/**
 * Created by luismp on 20/12/2018.
 */
public class GUIApostador extends GUI{

    /**
     * Método que recebe e trata os inputs da página após o login de um apostador
     * @return
     */
    protected static boolean apostadorLoggedInHandler() {
        String opcao = readLine();
        if (opcao.equals("1")) {
            showNotificacoes();
            confirmarContinuar();
            GUIMainPage.loggedInScene();
        } else if (opcao.equals("2")) {
            GUISaldo.gerirSaldoScene();
            GUISaldo.gerirSaldoHandler();
            confirmarContinuar();
            GUIMainPage.loggedInScene();
        } else if (opcao.equals("3")) {
            showResultados();
            confirmarContinuar();
            GUIMainPage.loggedInScene();
        } else if (opcao.equals("4")) {
            showEvents();
            confirmarContinuar();
            GUIMainPage.loggedInScene();
        } else if (opcao.equals("5")) {
            showApostas();
            confirmarContinuar();
            GUIMainPage.loggedInScene();
        } else if (opcao.equals("6")) {
            novaApostaForm();
            confirmarContinuar();
            GUIMainPage.loggedInScene();
        } else if (opcao.equals("0")) {
            terminarSessao();
            return false;
        } else {
            System.out.println("Input não reconhecido");
            confirmarContinuar();
            GUIMainPage.loggedInScene();
        }
        return true;
    }

    /**
     * Método que apresenta o formulário para registar uma nova Aposta
     * @see Aposta
     */
    private static void novaApostaForm() {
        Apostador atual = (Apostador) getAtual();
        System.out.println("---- Registar Nova Aposta ----");
        System.out.println("Indique em qual evento quer apostar");
        int idEvento = escolherIDEvento();
        if(idEvento == -1) {
            return;
        }
        Evento evento = getEvento(idEvento);
        printDetalhesEvento(evento);
        int idResultado = escolherResultado();
        Resultado resultado = evento.getResultado(idResultado);
        double quantia;
        quantia = escolherQuantia();
        tryRegistarAposta(atual, evento, resultado, quantia);
    }

    /**
     * Método que imprime no ecrã os detalhes de um evento
     * @param evento
     * @see Evento
     */
    private static void printDetalhesEvento(Evento evento) {
        System.out.println(evento);
        System.out.println("Indique qual o resultado que pretende apostar:\n" +
                "0 - Vitória de " + evento.getDesignacaoEquipa(1) + "- odd : " + evento.getResultado(0).getOdd() + "\n" +
                "1 - Empate - odd : " + evento.getResultado(1).getOdd() + "\n" +
                "2 - Vitória de " + evento.getDesignacaoEquipa(2) + "- odd : " + evento.getResultado(2).getOdd() + "\n");
    }

    /**
     * Método que tenta registar uma nova Aposta no sistema
     * @param atual
     * @param evento
     * @param resultado
     * @param quantia
     * @see Aposta
     */
    private static void tryRegistarAposta(Apostador atual, Evento evento, Resultado resultado, double quantia) {
        try {
            atual.registarAposta(evento, resultado, quantia);
        } catch (SaldoInsuficienteException e) {
            System.out.println("Saldo insuficiente. Aposta não registada");
            return;
        }
    }

    /**
     * Método que permite ao Apostador selecionar qual a quantia a apostar
     * @return Quantia
     */
    private static double escolherQuantia() {
        System.out.println("Qual a quantia que quer apostar?");
        double quantia;
        while (true) {
            String qt = readLine();
            if (!isDouble(qt)) {
                System.out.println("Quantia inválida. Insira uma nova quantia");
            } else {
                quantia = Double.parseDouble(qt);
                break;
            }
        }
        return quantia;
    }

    /**
     * Método que permite ao Apostador selecionar qual o Resultado em que quer apostar
     * @return Resultado
     */
    private static int escolherResultado() {
        int idResultado = 0;
        while (true) {
            String idres = readLine();
            if (idres.equals("0")) {
                idResultado = 0;
                break;
            } else if (idres.equals("1")) {
                idResultado = 1;
                break;
            } else if (idres.equals("2")) {
                idResultado = 2;
                break;
            } else {
                System.out.println("Resultado inválido. Insira um resultado válido");
            }
        }
        return idResultado;
    }

    /**
     * Método que permite ao Apsotador selecionar qual o identificador do evento em que quer apostar
     * @return ID Evento
     */
    private static int escolherIDEvento() {
        int idEvento = 0;
        while (true) {
            String idev = readLine();
            if (isInteger(idev)) {
                idEvento = Integer.parseInt(idev);
                if (isEventoAberto(idEvento)) break;
                else {
                    System.out.println("Evento não disponível");
                    idEvento = -1;
                    break;
                }
            } else {
                System.out.println("Input não reconhecido");
                idEvento = -1;
                break;
            }
        }
        return idEvento;
    }

    /**
     * Método que imprime todos os resultados no ecrã
     */
    private static void showResultados() {
        System.out.println("---- Resultados ----");
        for (Evento e : getEventos().values()) {
            if (e.getEstado() == 'F') {
                System.out.println(e.toString());
            }
        }
        System.out.println("--------------------");

    }

    /**
     * Método que imprime no ecrã todas as Apostas que um Apostador registou
     */
    private static void showApostas() {
        Apostador atual = (Apostador) getAtual();
        System.out.println("---- Apostas Realizadas ----");
        if (atual.getApostas().size() == 0) {
            System.out.println("Não há apostas");
        } else {
            for (Aposta a : atual.getApostas().values()) {
                System.out.println(a.toString());
            }
        }
        System.out.println("----------------------------");
    }

    /**
     * Método que imprime no ecrã todas as Notificações enviadas a um Apostador
     */
    private static void showNotificacoes() {
        Apostador atual = (Apostador) getAtual();
        System.out.println("---- Notificações ----");
        if (atual.getNotificacoes().size() == 0) {
            System.out.println("Não há notificações");
        } else {
            for (Notificacao n : atual.getNotificacoes()) {
                System.out.println(n.toString());
            }
        }
        System.out.println("---------------------");
    }

}
<file_sep>/README.md
# AS_TP2
Arquiteturas de Software - TP2- Refactoring
<file_sep>/src/Business/Resultado.java
package Business;

import java.io.Serializable;

/**
 * Created by luismp on 11/11/2018.
 */
public class Resultado implements Serializable {
    public String designacao;
    public double odd;

    /**
     * Construtor Vazio de um Resultado
     */
    public Resultado(){
        this.designacao = "";
        this.odd = 0;
    }

    /**
     * Construtor parametrizado de um Resultado
     * @param designacao
     * @param odd
     */
    public Resultado(String designacao, double odd){
        this.designacao = designacao;
        this.odd = odd;
    }

    /**
     * Getter da Designação de um Resultado
     * @return Designação
     */
    public String getDesignacao() {
        return designacao;
    }

    /**
     * Getter da Odd de um Resultado
     * @return Odd
     */
    public double getOdd() {
        return odd;
    }

    /**
     * Método equals
     * @param object
     * @return Boolean
     */
    public boolean equals(Object object){
        if(object == this) return true;

        if(object==null || object.getClass() != this.getClass()) return false;

        Resultado resultado = (Resultado) object;

        return resultado.getDesignacao().equals(this.getDesignacao()) && resultado.getOdd() == this.getOdd();
    }

    /**
     * toString
     * @return String
     */
    public String toString(){
        StringBuilder string = new StringBuilder();
        string
            .append("----Resultado----\nOdd : ")
            .append(this.getOdd())
            .append("\n")
            .append(this.getDesignacao())
            .append("\n-----------------\n");
        return string.toString();
    }
}
