/*
* Author: Balch
* Created: 9/4/14 12:26 AM
*
* This file is part of MockTrade.
*
* MockTrade 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 3 of the License, or
* (at your option) any later version.
*
* MockTrade 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 MockTrade. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2014
*/
package com.balch.mocktrade.order;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.View;
import android.view.ViewGroup;
import com.balch.android.app.framework.domain.ColumnDescriptor;
import com.balch.android.app.framework.domain.ExternalController;
import com.balch.android.app.framework.domain.ValidatorException;
import com.balch.android.app.framework.domain.widget.ControlMap;
import com.balch.android.app.framework.domain.widget.EditLayout;
import com.balch.android.app.framework.domain.widget.EnumEditLayout;
import com.balch.android.app.framework.types.Money;
import com.balch.mocktrade.TradeModelProvider;
import com.balch.mocktrade.R;
import com.balch.mocktrade.finance.FinanceModel;
import com.balch.mocktrade.finance.GoogleFinanceModel;
import java.util.ArrayList;
import java.util.List;
public class OrderEditController implements ExternalController<Order>, Parcelable {
public OrderEditController() {
}
@Override
public void onChanged(Context context, ColumnDescriptor descriptor, Object value, ControlMap controlMap) throws ValidatorException {
if (descriptor.getField().getName().equals(Order.FLD_STRATEGY)) {
onChangeStrategy((Order.OrderStrategy) value, controlMap);
} else if (descriptor.getField().getName().equals(Order.FLD_ACTION)) {
onChangeAction(context, (Order.OrderAction) value, controlMap);
}
}
@Override
public void validate(Context context, Order order, ControlMap controlMap) throws ValidatorException {
StockSymbolLayout symbolControl = controlMap.get(Order.FLD_SYMBOL);
Money price = symbolControl.getPrice();
if (order.getStrategy() == Order.OrderStrategy.MANUAL) {
price = order.getLimitPrice();
}
Money cost = Money.multiply(price, order.getQuantity());
boolean hasAvailableFunds = ((order.getAction() == Order.OrderAction.SELL) ||
(cost.getDollars() <= order.getAccount().getAvailableFunds().getDollars()));
QuantityPriceLayout quantityControl = controlMap.get(Order.FLD_QUANTITY);
quantityControl.setCost(cost, hasAvailableFunds);
if (!hasAvailableFunds) {
throw new ValidatorException(quantityControl.getContext().getString(R.string.quantity_edit_error_insufficient_funds));
} else if ((cost.getDollars() == 0.0) && (order.getStrategy() != Order.OrderStrategy.MANUAL)) {
throw new ValidatorException(quantityControl.getContext().getString(R.string.quantity_edit_error_invalid_amount));
}
}
@Override
public void initialize(Context context, Order order, ControlMap controlMap) {
boolean controlEnabled = (order.getAction() == Order.OrderAction.BUY);
TradeModelProvider modelProvider = ((TradeModelProvider)context.getApplicationContext());
FinanceModel financeModel = new GoogleFinanceModel(modelProvider.getContext(),
modelProvider.getNetworkRequestProvider(), modelProvider.getSettings());
QuantityPriceLayout quantityControl = controlMap.get(Order.FLD_QUANTITY);
quantityControl.setOrderInfo(order);
quantityControl.setMarketIsOpen(financeModel.isMarketOpen());
quantityControl.setAccountInfo(order.getAccount());
quantityControl.setEnabled(controlEnabled);
EditLayout control = controlMap.get(Order.FLD_SYMBOL);
control.setEnabled(controlEnabled);
}
private void showControl(EditLayout control, boolean visible) {
if (control != null) {
if (control instanceof ViewGroup) {
((ViewGroup) control).setVisibility(visible ? View.VISIBLE : View.GONE);
}
}
}
private void onChangeStrategy(Order.OrderStrategy strategy, ControlMap controlMap) {
boolean showLimitPrice = false;
boolean showStopPrice = false;
boolean showStopPercent = false;
switch (strategy) {
case LIMIT:
case MANUAL:
showLimitPrice = true;
break;
case STOP_LOSS:
showStopPrice = true;
break;
case TRAILING_STOP_AMOUNT_CHANGE:
showStopPrice = true;
break;
case TRAILING_STOP_PERCENT_CHANGE:
showStopPercent = true;
break;
}
showControl(controlMap.get(Order.FLD_LIMIT_PRICE), showLimitPrice);
showControl(controlMap.get(Order.FLD_STOP_PERCENT), showStopPercent);
showControl(controlMap.get(Order.FLD_STOP_PRICE), showStopPrice);
}
private void onChangeAction(Context context, Order.OrderAction action, ControlMap controlMap) {
EditLayout control = controlMap.get(Order.FLD_STRATEGY);
if (control instanceof EnumEditLayout) {
int selectionIndex = 0;
Order.OrderStrategy strategy = (Order.OrderStrategy) control.getValue();
List<Object> enumValues = new ArrayList<>();
List<String> displayValues = new ArrayList<>();
String [] masterDisplayValues = context.getResources().getStringArray(strategy.getListResId());
for (int x = 0; x < Order.OrderStrategy.values().length; x++) {
Order.OrderStrategy s = Order.OrderStrategy.values()[x];
if ( ((action == Order.OrderAction.BUY) && s.isBuySupported()) ||
((action == Order.OrderAction.SELL) && s.isSellSupported())) {
if (s == strategy) {
selectionIndex = x;
}
enumValues.add(s);
displayValues.add(masterDisplayValues[x]);
}
}
((EnumEditLayout)control).setOptions(enumValues, displayValues, selectionIndex);
}
}
private OrderEditController(Parcel in) {
}
@Override
public void writeToParcel(Parcel dest, int flags) {
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<OrderEditController> CREATOR = new Creator<OrderEditController>() {
@Override
public OrderEditController createFromParcel(Parcel in) {
return new OrderEditController(in);
}
@Override
public OrderEditController[] newArray(int size) {
return new OrderEditController[size];
}
};
}