/*
 * Copyright (c) 2006-2009 OrangeSignal.com All rights reserved.
 * 
 * これは Apache ライセンス Version 2.0 (以下、このライセンスと記述) に
 * 従っています。このライセンスに準拠する場合以外、このファイルを使用
 * してはなりません。このライセンスのコピーは以下から入手できます。
 * 
 * http://www.apache.org/licenses/LICENSE-2.0.txt
 * 
 * 適用可能な法律がある、あるいは文書によって明記されている場合を除き、
 * このライセンスの下で配布されているソフトウェアは、明示的であるか暗黙の
 * うちであるかを問わず、「保証やあらゆる種類の条件を含んでおらず」、
 * 「あるがまま」の状態で提供されるものとします。
 * このライセンスが適用される特定の許諾と制限については、このライセンス
 * を参照してください。
 */

package jp.sf.orangesignal.chart.data.loader;

import java.applet.Applet;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import jp.sf.orangesignal.chart.data.BasicChartDataset;
import jp.sf.orangesignal.chart.event.DataLoadEvent;
import jp.sf.orangesignal.ta.data.model.Margin;
import jp.sf.orangesignal.ta.data.model.Price;
import jp.sf.orangesignal.ta.data.model.StockSplit;

public class DbChartDataLoader extends ChartDataLoader {

	/**
	 * デフォルトコンストラクタです。
	 */
	public DbChartDataLoader() {}

	@Override
	public void load(final Applet applet) {
		try {
//			DriverManager.registerDriver(new org.h2.Driver());
			final Connection conn = DriverManager.getConnection("jdbc:h2:file:../../src/test/resources/db/test;IFEXISTS=TRUE", "sa", "");
			try {
				conn.setReadOnly(true);
				final Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
				try {
					final List<Price> prices = getPrice(stmt);
					if (prices != null && prices.size() > 0) {
						final BasicChartDataset dataset = BasicChartDataset.createDataset(prices, getMargin(stmt), getSplit(stmt), null);
						super.send(new DataLoadEvent(this, dataset));
					}
				} finally {
					stmt.close();
				}
			} finally {
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	private static List<Price> getPrice(final Statement stmt) throws SQLException {
		stmt.execute("SELECT date, open, high, low, close, volume FROM price WHERE id = '4689t' ORDER BY date");

		final ResultSet r = stmt.getResultSet();
		final List<Price> list = new ArrayList<Price>();

		try {
			while (r.next()) {
				final Price o = new Price();
				o.setDate(r.getDate("date"));
				final BigDecimal open = r.getBigDecimal("open");
				o.setOpen(r.wasNull() ? null : open.intValueExact());
				final BigDecimal high = r.getBigDecimal("high");
				o.setHigh(r.wasNull() ? null : high.intValueExact());
				final BigDecimal low = r.getBigDecimal("low");
				o.setLow(r.wasNull() ? null : low.intValueExact());
				final BigDecimal close = r.getBigDecimal("close");
				o.setClose(r.wasNull() ? null : close.intValueExact());
				final BigDecimal volume = r.getBigDecimal("volume");
				o.setVolume(r.wasNull() ? null : volume.longValueExact());
				list.add(o);
			}

			return list;
		} finally {
			if (r != null) {
				try { r.close(); } catch (SQLException e) {}
			}
		}
	}

	private static List<Margin> getMargin(final Statement stmt) throws SQLException {
		stmt.execute("SELECT date, sold, bought FROM margin WHERE id = '4689t' ORDER BY date");

		final ResultSet r = stmt.getResultSet();
		final List<Margin> list = new ArrayList<Margin>();

		try {
			while (r.next()) {
				final Margin o = new Margin();
				o.setDate(r.getDate("date"));
				final BigDecimal sold = r.getBigDecimal("sold");
				o.setSold(r.wasNull() ? null : sold.doubleValue());
				final BigDecimal bought = r.getBigDecimal("bought");
				o.setBought(r.wasNull() ? null : bought.doubleValue());
				list.add(o);
			}

			return list;
		} finally {
			if (r != null) {
				try { r.close(); } catch (SQLException e) {}
			}
		}
	}

	private static List<StockSplit> getSplit(final Statement stmt) throws SQLException {
		stmt.execute("SELECT date, split FROM split WHERE id = '4689t' ORDER BY date");

		final ResultSet r = stmt.getResultSet();
		final List<StockSplit> list = new ArrayList<StockSplit>();

		try {
			while (r.next()) {
				final StockSplit o = new StockSplit();
				o.setDate(r.getDate("date"));
				final BigDecimal ratio = r.getBigDecimal("split");
				o.setSplit(r.wasNull() ? null : ratio.doubleValue());
				list.add(o);
			}

			return list;
		} finally {
			if (r != null) {
				try { r.close(); } catch (SQLException e) {}
			}
		}
	}

}
