/**
 * Copyright © 2009-2010, Bruce-Robert Pocock & Res Interactive, LLC.
 * All Rights Reserved. Licensed for perpetual use, modification, and/or
 * distribution by either party.
 * 
 * @author brpocock@star-hope.org
 */
package com.tootsville;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

import org.json.JSONException;
import org.json.JSONObject;
import org.starhope.appius.except.NotFoundException;
import org.starhope.appius.game.AppiusClaudiusCaecus;
import org.starhope.appius.game.inventory.AbstractItem;
import org.starhope.appius.game.inventory.GenericItemReference;
import org.starhope.appius.sql.SQLPeerDatum;
import org.starhope.appius.user.Nomenclator;
import org.starhope.appius.util.AppiusConfig;
import org.starhope.appius.util.CastsToJSON;
import org.starhope.appius.util.DataRecord;
import org.starhope.util.LibMisc;

/**
 * <h1>A Storage Bin</h1>
 * <p>
 * A Store contains StoreItems. Note that my original interpretation of
 * this was Store as in Storage, but it's come to also (usually) mean as
 * in Place Of Shopping.
 * </p>
 * <p>
 * XXX this class is still based upon {@link SQLPeerDatum}, it should be
 * migrated to {@link DataRecord}.
 * </p>
 * 
 * @see GenericItemReference
 * @author brpocock@star-hope.org
 */
public class Store extends SQLPeerDatum {

    /**
     * Java serialisation unique ID
     */
    private static final long serialVersionUID = -8503595537842839095L;
	
	/**
	 * Fetch up a store by its ID.
	 * 
	 * @param storeID WRITEME
	 * @return WRITEME
	 */
    public static Store getByID (final int storeID) {
        final Store self = new Store ();
        self.setID (storeID);
        final Vector <Integer> itemIDs = new Vector <Integer> ();
        Connection con = null;
        PreparedStatement st = null;
        ResultSet set = null;
        try {
            con = AppiusConfig.getDatabaseConnection ();
            st = con
            .prepareStatement ("SELECT itemID FROM storeItems WHERE storeID=? ORDER BY itemID DESC");
            st.setInt (1, storeID);
            set = st.executeQuery ();
            while (set.next ()) {
                itemIDs.add (Integer.valueOf (set.getInt (1)));
            }
        } catch (final SQLException e) {
            AppiusClaudiusCaecus.reportBug (e);
        } finally {
            LibMisc.closeAll (set, st, con);
        }
        for (final int i : itemIDs) {
            try {
                self.addItem (Nomenclator.getDataRecord (
                        GenericItemReference.class, i));
            } catch (final NotFoundException e) {
                AppiusClaudiusCaecus.reportBug (
						"Item is in a store, but doesn't exist = ID "
								+ i, e);
            }
        }
        return self;
    }

    /**
     * store's id
     */
    private int id = -1;

    /**
     * the set of all items found in the store
     */
    private final List <GenericItemReference> items = new LinkedList <GenericItemReference> ();
	
	/**
	 * WRITEME: document this method (brpocock@star-hope.org, Aug 27,
	 * 2009)
	 * 
	 * @param item WRITEME
	 */
    private void addItem (final GenericItemReference item) {
        items.add (item);
    }
	
	/**
	 * This is an overriding method.
	 * 
	 * @see org.starhope.appius.sql.SQLPeerDatum#flush()
	 */
    @Override
    public void flush () {
        AppiusClaudiusCaecus
        .reportBug ("Calling flush() on a Store: I don't do that.");
    }
	
	/**
	 * This is an overriding method.
	 * 
	 * @see org.starhope.appius.sql.SQLPeerDatum#getCacheUniqueID()
	 */
    @Override
    protected String getCacheUniqueID () {
        return String.valueOf (id);
    }

    /**
     * @return the id
     */
    public int getID () {
        return id;
    }
	
	/**
	 * WRITEME: document this method (brpocock@star-hope.org, Aug 27,
	 * 2009)
	 * 
	 * @return WRITEME
	 */
    public AbstractItem [] getItems () {
        return items.toArray (new GenericItemReference [items.size ()]);
    }
	
	/**
	 * This is an overriding method.
	 * 
	 * @see org.starhope.appius.sql.SQLPeerDatum#set(java.sql.ResultSet)
	 */
    @Override
    protected void set (final ResultSet rs) throws SQLException {
        items.clear ();
        while (rs.next ()) {
            try {
                items.add (Nomenclator.getDataRecord (GenericItemReference.class,
                        rs.getInt ("itemID")));
            } catch (final NotFoundException e) {
                AppiusClaudiusCaecus.reportBug (
                        "Item is in store, but doesn't exist", e);
            }
        }
    }

    /**
     * @param id1 the id to set
     */
    protected void setID (final int id1) {
        id = id1;
    }
	
	/**
	 * This is an overriding method.
	 * 
	 * @see CastsToJSON#toJSON()
	 */
    @Override
    public JSONObject toJSON () {
        final JSONObject storeInside = new JSONObject ();
        final JSONObject itemsJSON = new JSONObject ();
        int i = 0;

        for (final AbstractItem item : items) {
            try {
                itemsJSON.put (String.valueOf (i++ ), item.toJSON ());
            } catch (final JSONException e) {
                AppiusClaudiusCaecus.reportBug (e);
            }
        }
        try {
            storeInside.put ("items", itemsJSON);
        } catch (final JSONException e) {
            AppiusClaudiusCaecus.reportBug (e);
        }
        return storeInside;
    }

}
