001/*
002 * Trident - A Multithreaded Server Alternative
003 * Copyright 2014 The TridentSDK Team
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package net.tridentsdk.service;
018
019import net.tridentsdk.registry.Registry;
020
021import javax.annotation.concurrent.ThreadSafe;
022
023/**
024 * Handles player transactions, such objects, items, and currency
025 *
026 * <p>This is designed around multiple accounts which are not really accounts, but really a system of synchronizing
027 * transactions of a particular type. One account, for example, can be used for economy by one plugin, but that can
028 * interfere with another plugin's economy. A new account can be made supporting the same types used in the other plugin
029 * without interfering. Additionally, this has the advantage of being able to easily access another plugin's economy
030 * data, useful for providing hooks.</p>
031 *
032 * <p>Example:
033 * <pre><code>
034 *     // Economy
035 *     private static final Transactions handler = Registered.transactions();
036 *
037 *     // This must be static! Or you would end up with many different transactions
038 *     // to the wrong account
039 *     private static final int ECON_ID = handler.newAccount();
040 *
041 *     // Deposit
042 *     handler.deposit(ECON_ID, new Transaction&lt;Player, Player&gt;(int.class, playerFrom, playerTo, 100) {
043 *         &#64;Override public void doTransaction(Type type) {
044 *             // If check is not required but is a good debugging safeguard
045 *             if (type == Type.DEPOSIT) {
046 *                 receiver().sendMessage(sender().name() + " has sent you $" + amount());
047 *                 // You may give items here as well
048 *             }
049 *         }
050 *     });
051 *
052 *     // Remove
053 *     handler.withdraw(ECON_ID, new Transaction&lt;Player, Player&gt;(int.class, playerTo, playerTo, 100) {
054 *         &#64;Override public void doTransaction(Type type) {
055 *             // If check is not required but is a good debugging safeguard
056 *             if (type == Type.WITHDRAW) {
057 *                 sender().sendMessage("You have withdrawn $" + amount());
058 *                 // You may give items here as well
059 *             }
060 *         }
061 *     });
062 *
063 *     // Amount
064 *     int amount = handler.amount(ECON_ID, playerTo, int.class);
065 * </code></pre></p>
066 *
067 * <p>This class also contains global account IDs for economy and exchange [of items].</p>
068 *
069 * @author The TridentSDK Team
070 * @since 0.3-alpha-DP
071 */
072@ThreadSafe
073public interface Transactions extends Registry<Transaction> {
074    /**
075     * Creates a new account from the internal account clock
076     *
077     * @return the new account ID used in transactions
078     */
079    int newAcount();
080
081    /**
082     * The global economy ID to be used as the transaction ID
083     *
084     * <p>This is just a recommendation to use for plugins. You do not need to use this.</p>
085     *
086     * @return the global economy transaction ID
087     */
088    int globalEconomy();
089
090    /**
091     * The global exchange ID to be used as the transaction ID
092     *
093     * <p>This is just a recommendation to use for plugins. You do not need to use this.</p>
094     *
095     * @return the global exchange transaction ID
096     */
097    int globalExchange();
098
099    /**
100     * Performs a transaction from the transaction's sender to the transaction's receiver
101     *
102     * @param account the account ID to be used
103     * @param transaction the transaction to perform
104     */
105    void deposit(int account, Transaction transaction);
106
107    /**
108     * Withdraws an item from the account
109     *
110     * <p>IMPORTANT: The sender is the person withdrawing from the account. The receiver is not taken into
111     * consideration, so that is allowed to be {@code null}.</p>
112     *
113     * @param account the account ID to be used
114     * @param transaction the transaction to perform
115     * @return {@code false} if the account for the withdrawer does not exist, {@code true} if the transaction completes
116     *         successfully
117     */
118    boolean withdraw(int account, Transaction transaction);
119
120    /**
121     * Obtains the amount of an item as indicated by the amount field in each transaction
122     *
123     * @param account the account ID to be used
124     * @param person the object which the transactions were sent to that is checked by this amounting
125     * @param type the types to find the amount of. Also the parameter in
126     *             {@link Transaction#item()}
127     * @return the amount of an item of type {@code type} found the account of {@code person},
128     *         or {@code Integer.MIN_VALUE} if the account for {@code person} does not exist, or the accound ID is not
129     *         used for that person
130     */
131    int amount(int account, Object person, Object type);
132}