package fucoin.wallet;

import akka.actor.ActorRef;
import fucoin.AbstractNode;
import fucoin.gui.TransactionLogger;
import scala.concurrent.Future;

import java.io.Serializable;

/**
 *
 */
public abstract class AbstractWallet extends AbstractNode implements Serializable, TransactionLogger {

    /**
     * Currently amount of this wallet
     */
    protected int amount;

    /**
     * The name of this wallet (does never change, no duplicates in network assumed)
     */
    protected final String name;

    /**
     * Init. a wallet with a name.
     *
     * @param name Name of the Wallet
     */
    public AbstractWallet(String name) {
        this.name = name;
    }

    /**
     * Returns the name of the wallet
     *
     * @return Name of the wallet.
     */
    public String getName() {
        return this.name;
    }

    /**
     * Performs housekeeping operations, e.g. pushes
     * backedUpNeighbor-entries to other neighbors
     */
    public abstract void leave();

    /**
     * Returns the current amount of the wallet
     *
     * @return amount of the wallet
     */
    public int getAmount() {
        return amount;
    }

    /**
     * Set new Amount of the wallet.
     *
     * @param amount New amount of the wallet
     */
    public abstract void setAmount(int amount);

    /**
     * Add amount to current amount.
     *
     * @param amount value to add to current account.
     */
    public abstract void addAmount(int amount);

    /**
     * Sets the wallet into the active state.
     * TODO: Is this actually used/necessary/wanted?
     *
     * @param isActive
     */
    public abstract void setActive(boolean isActive);

    /**
     * Returns the
     *
     * @return
     */
    public abstract ActorRef getPreKnownNeighbour();

    /**
     * Returns the supervisor of this wallet
     *
     * @return
     */
    public abstract ActorRef getRemoteSuperVisorActor();

    /**
     * @param remoteSuperVisorActor
     */
    public abstract void setRemoteSuperVisorActor(ActorRef remoteSuperVisorActor);

    public abstract void deferSendOfSuperVisorActor(ActorRef destinationWallet);

    /**
     * Sends amount FUCs to the wallet with the address address
     *
     * @param address Recipients address
     * @param amount  Amount to send
     */
    public abstract void send(String address, int amount);

    /**
     * Sends amount FUCs to the wallet with the address address and the observer observer
     *
     * @param address
     * @param amount
     * @param observer
     */
    public abstract void send(String address, int amount, ActorRef observer);
}