package com.xeiam.xchange.cryptsy.service.polling;

import java.io.IOException;
import java.util.Date;

import com.xeiam.xchange.ExchangeException;
import com.xeiam.xchange.ExchangeSpecification;
import com.xeiam.xchange.NotAvailableFromExchangeException;
import com.xeiam.xchange.NotYetImplementedForExchangeException;
import com.xeiam.xchange.cryptsy.CryptsyAdapters;
import com.xeiam.xchange.cryptsy.CryptsyCurrencyUtils;
import com.xeiam.xchange.cryptsy.dto.CryptsyOrder.CryptsyOrderType;
import com.xeiam.xchange.cryptsy.dto.trade.CryptsyCancelOrderReturn;
import com.xeiam.xchange.cryptsy.dto.trade.CryptsyOpenOrdersReturn;
import com.xeiam.xchange.cryptsy.dto.trade.CryptsyPlaceOrderReturn;
import com.xeiam.xchange.cryptsy.dto.trade.CryptsyTradeHistoryReturn;
import com.xeiam.xchange.dto.Order.OrderType;
import com.xeiam.xchange.dto.trade.LimitOrder;
import com.xeiam.xchange.dto.trade.MarketOrder;
import com.xeiam.xchange.dto.trade.OpenOrders;
import com.xeiam.xchange.dto.trade.UserTrades;
import com.xeiam.xchange.service.polling.PollingTradeService;
import com.xeiam.xchange.service.polling.trade.TradeHistoryParams;

/**
 * @author ObsessiveOrange
 */
public class CryptsyTradeService extends CryptsyTradeServiceRaw implements PollingTradeService {

  /**
   * Constructor
   * 
   * @param exchangeSpecification
   *          The {@link ExchangeSpecification}
   */
  public CryptsyTradeService(ExchangeSpecification exchangeSpecification) {

    super(exchangeSpecification);
  }

  @Override
  public OpenOrders getOpenOrders() throws IOException, ExchangeException {

    CryptsyOpenOrdersReturn openOrdersReturnValue = getCryptsyOpenOrders();
    return CryptsyAdapters.adaptOpenOrders(openOrdersReturnValue);
  }

  @Override
  public String placeMarketOrder(MarketOrder marketOrder) throws IOException, ExchangeException {

    throw new NotAvailableFromExchangeException();
  }

  @Override
  public String placeLimitOrder(LimitOrder limitOrder) throws IOException, ExchangeException {

    CryptsyPlaceOrderReturn result =
        super.placeCryptsyLimitOrder(CryptsyCurrencyUtils.convertToMarketId(limitOrder.getCurrencyPair()), limitOrder.getType() == OrderType.ASK ? CryptsyOrderType.Sell : CryptsyOrderType.Buy,
            limitOrder.getTradableAmount(), limitOrder.getLimitPrice());

    return Integer.toString(result.getReturnValue());
  }

  @Override
  public boolean cancelOrder(String orderId) throws IOException, ExchangeException {

    CryptsyCancelOrderReturn ret = super.cancelSingleCryptsyLimitOrder(Integer.valueOf(orderId));
    return ret.isSuccess();
  }

  /**
   * @param arguments Vararg list of optional (nullable) arguments:
   *          (Long) arguments[0] Number of transactions to return
   *          (String) arguments[1] TradableIdentifier
   *          (String) arguments[2] TransactionCurrency
   *          (Long) arguments[3] Starting ID
   * @return Trades object
   * @throws IOException
   */
  @Override
  public UserTrades getTradeHistory(final Object... arguments) throws IOException, ExchangeException {

    Date startDate = new Date(0); // default value
    Date endDate = new Date(); // default value
    if (arguments.length == 2) {
      startDate = (Date) arguments[0];
      endDate = (Date) arguments[1];
    }

    CryptsyTradeHistoryReturn tradeHistoryReturnData = super.getCryptsyTradeHistory(startDate, endDate);

    return CryptsyAdapters.adaptTradeHistory(tradeHistoryReturnData);
  }

  @Override
  public UserTrades getTradeHistory(TradeHistoryParams params) throws ExchangeException, NotAvailableFromExchangeException, NotYetImplementedForExchangeException, IOException {

    throw new NotYetImplementedForExchangeException();
  }

  @Override
  public com.xeiam.xchange.service.polling.trade.TradeHistoryParams createTradeHistoryParams() {

    return null;
  }

}

@@ -1097,32 +1097,39 @@
 e.polling.trade.
+Default
 TradeHistoryPara
@@ -1130,16 +1130,166 @@
 ryParams
+TimeSpan;%0Aimport com.xeiam.xchange.service.polling.trade.TradeHistoryParams;%0Aimport com.xeiam.xchange.service.polling.trade.TradeHistoryParamsTimeSpan
 ;%0A%0A/**%0A 
@@ -3613,32 +3613,205 @@
 turnData);%0A  %7D%0A%0A
+  /**%0A   * @param params%0A   *          Can optionally implement %7B@link TradeHistoryParamsTimeSpan%7D. All other%0A   *          TradeHistoryParams types will be ignored.%0A   */%0A%0A
   @Override%0A  pu
@@ -3992,62 +3992,575 @@
     
-throw new NotYetImplementedForExch
+CryptsyTradeHistoryReturn tradeHistoryReturnData;%0A    if (params instanceof TradeHistoryParamsTimeSpan) %7B%0A      TradeHistoryParamsTimeSpan timeSpan = (TradeHistoryParamsTimeSpan) params;%0A      tradeHistoryReturnData = super.getCryptsyTradeHistory(timeSpan.getStartTime(), timeSp
 an
+.
 ge
-Exception();%0A  %7D
+tEndTime());%0A    %7D%0A    else %7B%0A      tradeHistoryReturnData = super.getCryptsyTradeHistory(null, null);%0A    %7D%0A    return CryptsyAdapters.adaptTradeHistory(tradeHistoryReturnData);%0A  %7D%0A%0A  /**%0A   * Create %7B@link TradeHistoryParams%7D that supports %7B@link TradeHistoryParamsTimeSpan%7D.%0A   */
 %0A%0A  
@@ -4679,19 +4679,54 @@
 return n
-ull
+ew DefaultTradeHistoryParamsTimeSpan()
 ;%0A  %7D%0A%0A%7D

Implement TradeHistoryParams based query.