/*
 * Copyright 2020       Thomas Baumgart <tbaumgart@kde.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef INVESTACTIVITIES_H
#define INVESTACTIVITIES_H

// ----------------------------------------------------------------------------
// QT Includes

#include <qglobal.h>
class QStringList;

// ----------------------------------------------------------------------------
// KDE Includes

// ----------------------------------------------------------------------------
// Project Includes

class MyMoneyMoney;
class MyMoneySplit;
class SplitModel;
class InvestTransactionEditor;

namespace eMyMoney { namespace Split { enum class InvestmentTransactionType; } }

namespace Invest
{

class ActivityPrivate;
class Activity
{
  Q_DISABLE_COPY(Activity)

public:
  typedef enum {
    Unused,
    Optional,
    Mandatory
  } fieldRequired_t;

  virtual eMyMoney::Split::InvestmentTransactionType type() const = 0;
  virtual void showWidgets() const = 0;

  virtual void adjustStockSplit(MyMoneySplit& stockSplit) = 0;

  virtual ~Activity();

  virtual void loadPriceWidget(const MyMoneySplit& split);
  virtual MyMoneyMoney totalAmount(const MyMoneySplit& stockSplit, const SplitModel* feesModel, const SplitModel* interestModel) const;

  virtual MyMoneyMoney sharesFactor() const;
  virtual MyMoneyMoney feesFactor() const;
  virtual MyMoneyMoney interestFactor() const;

  virtual fieldRequired_t feesRequired() const { return Unused; }
  virtual fieldRequired_t interestRequired() const { return Unused; }
  virtual fieldRequired_t assetAccountRequired() const { return Unused; }
  virtual fieldRequired_t priceRequired() const { return Unused; }

  bool haveFees( fieldRequired_t = Mandatory) const;
  bool haveInterest( fieldRequired_t = Mandatory) const;

protected:
  explicit Activity(InvestTransactionEditor* editor);
  virtual QString priceLabelText() const;
  virtual QString sharesLabelText() const;

  bool haveCategoryAndAmount(const QString& category, const QString& amount, fieldRequired_t optional) const;
  void setLabelText(const QString& idx, const QString& txt) const;
  void setWidgetVisibility(const QStringList& widgetIds, bool visible) const;
  void setupWidgets(const QStringList& activityWidgets) const;

protected:
  ActivityPrivate* d_ptr;
  Q_DECLARE_PRIVATE(Activity)
};

class Buy : public Activity
{
public:
  explicit Buy(InvestTransactionEditor* editor);
  ~Buy() override;
  eMyMoney::Split::InvestmentTransactionType type() const override;
  void showWidgets() const override;
  virtual void adjustStockSplit(MyMoneySplit&) override {}

  fieldRequired_t feesRequired() const override { return Optional; }
  fieldRequired_t assetAccountRequired() const override { return Mandatory; }
  fieldRequired_t priceRequired() const override { return Mandatory; }
};

class Sell : public Activity
{
public:
  explicit Sell(InvestTransactionEditor* editor);
  ~Sell() override;
  eMyMoney::Split::InvestmentTransactionType type() const override;
  void showWidgets() const override;
  virtual void adjustStockSplit(MyMoneySplit&) override {}

  MyMoneyMoney sharesFactor() const override;
  fieldRequired_t feesRequired() const override { return Optional; }
  fieldRequired_t interestRequired() const override { return Optional; }
  fieldRequired_t assetAccountRequired() const override;
  fieldRequired_t priceRequired() const override { return Mandatory; }
};

class Div : public Activity
{
public:
  explicit Div(InvestTransactionEditor* editor);
  ~Div() override;
  eMyMoney::Split::InvestmentTransactionType type() const override;
  void showWidgets() const override;
  virtual void adjustStockSplit(MyMoneySplit&) override {}
  fieldRequired_t feesRequired() const override { return Optional; }
  fieldRequired_t interestRequired() const override { return Mandatory; }
  fieldRequired_t assetAccountRequired() const override { return Mandatory; }
};

class Reinvest : public Activity
{
public:
  explicit Reinvest(InvestTransactionEditor* editor);
  ~Reinvest() override;
  eMyMoney::Split::InvestmentTransactionType type() const override;
  void showWidgets() const override;
  virtual void adjustStockSplit(MyMoneySplit&) override {}
  MyMoneyMoney totalAmount(const MyMoneySplit& stockSplit, const SplitModel* feesModel, const SplitModel* interestModel) const override;

  fieldRequired_t feesRequired() const override { return Optional; }
  fieldRequired_t interestRequired() const override { return Mandatory; }
  fieldRequired_t priceRequired() const override { return Mandatory; }
};

class Add : public Activity
{
public:
  explicit Add(InvestTransactionEditor* editor);
  ~Add() override;
  eMyMoney::Split::InvestmentTransactionType type() const override;
  void showWidgets() const override;
  void adjustStockSplit(MyMoneySplit& stockSplit) override;
  MyMoneyMoney totalAmount(const MyMoneySplit& stockSplit, const SplitModel* feesModel, const SplitModel* interestModel) const override;
};

class Remove : public Activity
{
public:
  explicit Remove(InvestTransactionEditor* editor);
  ~Remove() override;
  eMyMoney::Split::InvestmentTransactionType type() const override;
  void showWidgets() const override;
  void adjustStockSplit(MyMoneySplit& stockSplit) override;
  MyMoneyMoney totalAmount(const MyMoneySplit& stockSplit, const SplitModel* feesModel, const SplitModel* interestModel) const override;

  virtual MyMoneyMoney sharesFactor() const override;
};

class Split : public Activity
{
public:
  explicit Split(InvestTransactionEditor* editor);
  ~Split() override;
  eMyMoney::Split::InvestmentTransactionType type() const override;
  void showWidgets() const override;
  virtual void adjustStockSplit(MyMoneySplit& stockSplit) override;
  MyMoneyMoney totalAmount(const MyMoneySplit& stockSplit, const SplitModel* feesModel, const SplitModel* interestModel) const override;

protected:
  QString sharesLabelText() const override;
};

class IntInc : public Activity
{
public:
  explicit IntInc(InvestTransactionEditor* editor);
  ~IntInc() override;
  eMyMoney::Split::InvestmentTransactionType type() const override;
  void showWidgets() const override;
  virtual void adjustStockSplit(MyMoneySplit&) override {}

  fieldRequired_t feesRequired() const override { return Optional; }
  fieldRequired_t interestRequired() const override { return Mandatory; }
  fieldRequired_t assetAccountRequired() const override { return Mandatory; }
};

} // namespace Invest

#endif // INVESTACTIVITIES_H

