package org.bucksch.zeipis.recorder;
import org.bucksch.zeipis.all.*;
import java.sql.*;

abstract public class DVBTransponder
{
  /**
   * Factory function. Creates an object of an
   * appropriate DBVTransponder subtype,
   * depending on the dvbsubtype column
   * in the database row that you pass in
   * (as transponder ID).
   * @param transponderid
   */
  static public DVBTransponder createFromDatabase(int transponderid)
    throws Misconfiguration, SQLException
  {
    return createFromDatabase(readFromDatabase(transponderid));
  }
  /**
   * Factory function. Same as above,
   * just that you pass in an already read DB row.
   * @param transponderid
   */
  static public DVBTransponder createFromDatabase(ResultSet rs)
    throws Misconfiguration, SQLException
  {
    DVBTransponder result;
    String dvbsubtype = rs.getString("dvbsubtype");
    if (dvbsubtype.equals("DVB-S2"))
      result = new DVBS2Transponder();
    else if (dvbsubtype.equals("DVB-S"))
      result = new DVBSTransponder();
    else if (dvbsubtype.equals("DVB-T"))
      result = new DVBTTransponder();
    else if (dvbsubtype.equals("DVB-C"))
      result = new DVBCTransponder();
    else
      throw new Misconfiguration("DVB transponder subtype " + dvbsubtype + " unknown");

    result.readFromDatabaseResultSet(rs);
    return result;
  }
  /**
   * Creates an un-inited object.
   * Needed by channel importers to create a channel from data other than the DB.
   * You need to populate it ASAP, or not use it as valid channel object,
   * because it violates the assumptions for it.
   *
   * DO NOT use such an object for tuning or anything else in the core app!
   * It's only a placeholder object, from DVBScan to ChannelsToDBImporter or similar. 
   */
  public DVBTransponder()
  {
    myTransponderDBID = -1;
  }
  static protected ResultSet readFromDatabase(int transponderid)
    throws Misconfiguration, SQLException
  {
    ResultSet rs;
    try {
      rs = DB.me.database().createStatement().executeQuery("SELECT * FROM dvb_transponder WHERE channelid = " + transponderid);
      if ( ! rs.first())
        throw new NoSuchFieldException();
      return rs;
    } catch (Exception e) {
      throw new IllegalStateException("Transponder ID " + transponderid + " not found in database", e);
    }
  }
  protected void readFromDatabaseResultSet(ResultSet rs)
    throws Misconfiguration, SQLException
  {
    myTransponderDBID = rs.getInt("dvb_transponderid");

    frequency = rs.getInt("frequency");
    symbolrate = rs.getInt("symbolrate");
    modulation = rs.getString("modulation").toUpperCase();
    fec = rs.getString("fec_inner").toUpperCase();
  }

  public boolean sameTransponder(DVBTransponder other, boolean strict)
  {
    if (other.getClass() != getClass())
      return false;
    if (strict)
      return this == other;
    else
      return frequency == other.frequency &&
           symbolrate == other.symbolrate;
  }
  /**
   * @returns DVB-S, DVB-S2 etc., depending on concrete type / transponder
   */
  public String dvbSubtype()
  {
    return myDVBSubtype;
  }

  public String toString()
  {
    return myDVBSubtype + " transponder ID " + myTransponderDBID;
  }

  // Data
  protected String myDVBSubtype;
  protected int myTransponderDBID;
  // from stream
  //public int transportid = -1;
  //public int networkid = -1;
  //public int serviceversion = -1;

  // physical tuning, shared by several or all DVB subtypes
  public int frequency;
  public int symbolrate;
  public String fec;
  public String modulation;
}
