/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.core.impl;

import java.sql.*;
import java.util.Random;
import com.silverwrist.util.cache.CacheMap;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.core.internals.EnvEngine;
import com.silverwrist.venice.db.*;
import com.silverwrist.venice.except.*;

class AdvertisementImpl implements Advertisement
{
  /*--------------------------------------------------------------------------------
   * Static data members
   *--------------------------------------------------------------------------------
   */

  private static Random rng = new Random(System.currentTimeMillis());
  private static CacheMap ad_cache = new CacheMap(500);

  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private EnvEngine env;             // execution environment
  private int adid;                  // ad ID
  private String imagepath;          // image path
  private short style;               // ad style
  private String caption;            // ad caption
  private String linkurl;            // ad link URL

  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  protected AdvertisementImpl(EnvEngine env, ResultSet rs) throws SQLException
  {
    this.env = env;
    this.adid = rs.getInt("adid");
    this.imagepath = rs.getString("imagepath");
    this.style = rs.getShort("pathstyle");
    this.caption = rs.getString("caption");
    this.linkurl = rs.getString("linkurl");

  } // end constructor

  /*--------------------------------------------------------------------------------
   * Internal functions
   *--------------------------------------------------------------------------------
   */

  private static final Advertisement getTheAd(EnvEngine env, Statement stmt, int ad_id) throws SQLException
  {
    Integer my_ad_id = new Integer(ad_id);
    Advertisement rc = (Advertisement)(ad_cache.get(my_ad_id));
    if (rc!=null)
      return rc;

    ResultSet rs = stmt.executeQuery("SELECT * FROM adverts WHERE adid = " + ad_id + ";");
    if (!(rs.next()))
      return null;
    rc = new AdvertisementImpl(env,rs);
    SQLUtil.shutdown(rs);
    ad_cache.put(my_ad_id,rc);
    return rc;
    
  } // end getTheAd

  /*--------------------------------------------------------------------------------
   * Implementations from interface Advertisement
   *--------------------------------------------------------------------------------
   */

  public int getAdID()
  {
    return adid;

  } // end getAdID

  public String getImagePath()
  {
    return imagepath;

  } // end getImagePath

  public short getImagePathStyle()
  {
    return style;

  } // end getImagePathStyle

  public String getCaption()
  {
    return caption;

  } // end getCaption

  public String getLinkURL()
  {
    return linkurl;

  } // end getLinkURL

  public void hit(String remote_addr)
  { // this does nothing right now
  } // end hit

  /*--------------------------------------------------------------------------------
   * Static functions for use within package
   *--------------------------------------------------------------------------------
   */

  static Advertisement getAdByID(EnvEngine env, int id)
  {
    Connection conn = null;
    Statement stmt = null;

    try
    { // get a database connection and call the internal function
      conn = env.getConnection();
      stmt = conn.createStatement();
      return getTheAd(env,stmt,id);

    } // end try
    catch (SQLException e)
    { // database error - no ad
      return null;

    } // end catch
    finally
    { // make sure the connection is released before we go
      SQLUtil.shutdown(stmt);
      env.releaseConnection(conn);

    } // end finally

  } // end getAdByID

  static Advertisement getRandomAd(EnvEngine env)
  {
    Connection conn = null;
    Statement stmt = null;

    try
    { // get a database connection and call the internal function
      conn = env.getConnection();
      stmt = conn.createStatement();
      ResultSet rs = stmt.executeQuery("SELECT MAX(adid) FROM adverts;");
      if (!(rs.next()))
	throw new InternalStateError("getRandomAd() must be able to find MAX(adid)!");
      int maximum = rs.getInt(1);
      
      for (int i=0; i<100; i++)
      { // select an ad ID
	int ad_id = rng.nextInt(maximum) + 1;
	Advertisement rc = getTheAd(env,stmt,ad_id);
	if (rc!=null)
	  return rc;

      } // end for

      // else just dump out and return null

    } // end try
    catch (SQLException e)
    { // database error - no ad
      return null;

    } // end catch
    finally
    { // make sure the connection is released before we go
      SQLUtil.shutdown(stmt);
      env.releaseConnection(conn);

    } // end finally

    return null;  // no ad
    
  } // end getRandomAd

} // end class AdvertisementImpl
