//---------------------------------------------------------------------------

#include <clx.h>
#pragma hdrstop

#include "Channel.h"
#include "SQL.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.xfm"
TChannelWin *ChannelWin;
//---------------------------------------------------------------------------
__fastcall TChannelWin::TChannelWin(TComponent* Owner)
        : TForm(Owner)
{
}

void __fastcall TChannelWin::FormCreate(TObject *Sender)
{
  // check for channel preset hack (channnum_real)
  TStringList* columns = new TStringList;
  SQLModule->Conn->GetFieldNames("channel", columns);
  bool channelPresetHack = columns->IndexOf("channum_real") != -1;

  if (channelPresetHack)
  {
    ChannumOldLabel->Visible = false;
  }
  else
  {
    PresetLabel->Visible = false;
    ChannumReal1Label->Visible = false;
    ChannumReal2Label->Visible = false;
    ChannumRealEdit->Visible = false;
    ChannumRealEdit->DataField = "";
  }
}
//---------------------------------------------------------------------------

void __fastcall TChannelWin::SetSourceID(int a_sourceid)
{
  sourceid = a_sourceid;

  // Setting filters
  AnsiString filter;
  filter.sprintf("sourceid=%d", sourceid);
  SourceDataSet->Filter = filter;
  SourceDataSet->Active = true;
  ChannelDataSet->Filter = filter;
  ChannelDataSet->Active = true;
  CardtypeDataSet->Filter = filter;
  CardtypeDataSet->Active = true;

  // Setting channel type
  CardtypeDataSet->First();
  AnsiString major_type_str = VarToStr(CardtypeDataSet->FieldValues["cardtype"]);
  AnsiString minor_type_str = VarToStr(CardtypeDataSet->FieldValues["dvb_type"]);
  if (major_type_str == "V4L")
    cardtype = analog_soft;
  else if (major_type_str == "MPEG")
    cardtype = analog_hard;
  else if (major_type_str == "DVB")
  {
    if (minor_type_str == "S")
      cardtype = dvb_s;
    else if (minor_type_str == "T")
      cardtype = dvb_t;
    else if (minor_type_str == "C")
      cardtype = dvb_c;
    else
      cardtype = ct_invalid;
  }
  else
    cardtype = ct_invalid;

  // Setting UI for channel type
  if (cardtype == analog_soft || cardtype == analog_hard)
  {
    AnalogPane->Visible = true;
    DVBPane->Visible = false;
  }
  else if (cardtype == dvb_s || cardtype == dvb_t || cardtype == dvb_c)
  {
    AnalogPane->Visible = false;
    DVBPane->Visible = true;
    if (cardtype == dvb_s)
    {
      DVBSPane->Visible = true;
      DVBTPane->Visible = false;
      DVBCPane->Visible = false;
      DVBSLabel->Visible = true;
      DVBTLabel->Visible = false;
      DVBCLabel->Visible = false;
    }
    else if (cardtype == dvb_t)
    {
      DVBSPane->Visible = false;
      DVBTPane->Visible = true;
      DVBCPane->Visible = false;
      DVBSLabel->Visible = false;
      DVBTLabel->Visible = true;
      DVBCLabel->Visible = false;
    }
    else if (cardtype == dvb_c)
    {
      DVBSPane->Visible = false;
      DVBTPane->Visible = false;
      DVBCPane->Visible = true;
      DVBSLabel->Visible = false;
      DVBTLabel->Visible = false;
      DVBCLabel->Visible = true;
    }
  }
  else
  {
    AnalogPane->Visible = false;
    DVBPane->Visible = false;
  }
}

void __fastcall TChannelWin::NewSource()
{
  SourceDataSet->Active = true;
  SourceDataSet->Append();
  sourceid = SQLModule->GetNewID("videosource", "sourceid");
  SourceDataSet->FieldValues["sourceid"] = sourceid;
  SourceDataSet->FieldValues["name"] = "change this";
  SourceDataSet->FieldValues["xmltvgrabber"] = "change this";
  SourceDataSet->FieldValues["userid"] = "unused";

  SetSourceID(sourceid);
}
//---------------------------------------------------------------------------
void __fastcall TChannelWin::ApplyActionExecute(TObject *Sender)
{
  SourceDataSet->ApplyUpdates(0);
  ChannelDataSet->ApplyUpdates(0);
  if (DVBDataSet->State != dsInactive)
    DVBDataSet->ApplyUpdates(0);
}
//---------------------------------------------------------------------------
bool __fastcall TChannelWin::isDirty()
{
  /* ClientDataSets can cache the whole data, including all unsaved
     changes to it.
     Modified reports about the currently edited record, while
     ChangeCount appearantly only reports about confirmed (but not yet
     saved to the real data store) changes to records.
     Modified doesn't work either :-(. Using State. */
  return SourceDataSet->State == dsEdit || SourceDataSet->ChangeCount > 0 ||
         ChannelDataSet->State == dsEdit || ChannelDataSet->ChangeCount > 0 ||
         DVBDataSet->State == dsEdit || DVBDataSet->ChangeCount > 0;
}

void __fastcall TChannelWin::FormCloseQuery(TObject *Sender,
      bool &CanClose)
{
  if (!isDirty())
  {
    CanClose = true;
    return;
  }

  int request = MessageDlg("Save changes",
                           "Do you want to save your changes in the database?",
                           mtConfirmation,
                           TMsgDlgButtons() << mbYes << mbNo << mbCancel,
                           0, mbYes);
  if (request == mrYes)
  {
    ApplyActionExecute(this);
    CanClose = true;
  }
  else if (request == mrNo)
  {
    SourceDataSet->CancelUpdates();
    ChannelDataSet->CancelUpdates();
    if (cardtype == dvb_s || cardtype == dvb_t || cardtype == dvb_c)
      DVBDataSet->CancelUpdates();
    CanClose = true;
  }
  else
    CanClose = false;
}
//---------------------------------------------------------------------------
#include "stdio.h"

void __fastcall TChannelWin::ChannelDataSetNewRecord(TDataSet *DataSet)
{
  int chanid = SQLModule->GetNewID("channel", "chanid");
  ChannelDataSet->FieldValues["chanid"] = chanid;
  ChannelDataSet->FieldValues["sourceid"] = sourceid;
  printf("new %d\n", chanid);

  if (cardtype != dvb_s && cardtype != dvb_t && cardtype != dvb_c)
    return;
  DVBDataSet->Filter = AnsiString().sprintf("chanid=%d", chanid);
  DVBDataSet->Active = true;
  DVBDataSet->Insert();
}
//---------------------------------------------------------------------------

void __fastcall TChannelWin::DVBDataSetNewRecord(TDataSet *DataSet)
{
  printf("after insert\n");
  Variant chanid_var = ChannelDataSet->FieldValues["chanid"];
  if (chanid_var.IsNull()) // no channels at all yet
    ChannelDataSet->Insert(); // create one
  DVBDataSet->FieldValues["chanid"] = chanid_var;
}
//---------------------------------------------------------------------------

void __fastcall TChannelWin::ChannelDataSetBeforePost(TDataSet *DataSet)
{
  printf("before post\n");
  if (DVBDataSet->State == dsEdit || DVBDataSet->State == dsInsert)
    DVBDataSet->Post();
}
//---------------------------------------------------------------------------

void __fastcall TChannelWin::ChannelDataSetBeforeCancel(TDataSet *DataSet)
{
  printf("before cancel\n");
  if (DVBDataSet->State == dsEdit || DVBDataSet->State == dsInsert)
    DVBDataSet->Cancel();
}
//---------------------------------------------------------------------------

void __fastcall TChannelWin::ChannelDataSetBeforeDelete(TDataSet *DataSet)
{
  printf("before delete\n");
  if (DVBDataSet->State != dsInactive)
    DVBDataSet->Delete();
}
//---------------------------------------------------------------------------

void __fastcall TChannelWin::ChannelDataSetAfterScroll(TDataSet *DataSet)
{
  printf("scroll\n");
  if (cardtype != dvb_s && cardtype != dvb_t && cardtype != dvb_c)
    return;
//  if (DVBDataSet->State == dsEdit || DVBDataSet->State == dsInsert)
//    DVBDataSet->Cancel(); // insert and then scroll doesn't invoke scroll
  Variant chanid_var = ChannelDataSet->FieldValues["chanid"];
  if (chanid_var.IsNull())
  {
    DVBDataSet->Active = false;
    return;
  }
  DVBDataSet->Filter = AnsiString().sprintf("chanid=%d", (int) chanid_var);
  DVBDataSet->Active = true;
}

/* generally, I'd need to care about Cancel, Post etc. on the DVBDataSet
    as well, but there is no way to invoke those (to my knowledge), so
    I don't care. */
//---------------------------------------------------------------------------

