// rdreport.cpp
//
// Abstract a Rivendell Report Descriptor
//
//   (C) Copyright 2002-2021 Fred Gleason <fredg@paravelsystems.com>
//
//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License version 2 as
//   published by the Free Software Foundation.
//
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public
//   License along with this program; if not, write to the Free Software
//   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//

#include <QFile>

#include "rdapplication.h"
#include "rdconf.h"
#include "rddatedecode.h"
#include "rdescape_string.h"
#include "rdlog_line.h"
#include "rdreport.h"

RDReport::RDReport(const QString &rptname,RDStation *station,RDConfig *config,
		   QObject *parent)
{
  report_name=rptname;
  report_station=station;
  report_config=config;
  report_error_code=RDReport::ErrorOk;
}


QString RDReport::name() const
{
  return report_name;
}


bool RDReport::exists() const
{
  QString sql=QString("select `NAME` from `REPORTS` where ")+
    "`NAME`='"+RDEscapeString(report_name)+"'";
  RDSqlQuery *q=new RDSqlQuery(sql);
  if(!q->first()) {
    delete q;
    return false;
  }
  delete q;
  return true;
}


QString RDReport::description() const
{
  return RDGetSqlValue("REPORTS","NAME",report_name,"DESCRIPTION").toString();
}


void RDReport::setDescription(const QString &desc) const
{
  SetRow("DESCRIPTION",desc);
}


RDReport::ExportFilter RDReport::filter() const
{
  return (RDReport::ExportFilter)RDGetSqlValue("REPORTS","NAME",report_name,
					      "EXPORT_FILTER").toInt();
}


void RDReport::setFilter(ExportFilter filter) const
{
  SetRow("EXPORT_FILTER",(int)filter);
}


QString RDReport::exportPath(ExportOs ostype) const
{
  return RDGetSqlValue("REPORTS","NAME",report_name,
		       OsFieldName(ostype)+"EXPORT_PATH").toString();
}


void RDReport::setExportPath(ExportOs ostype,const QString &path) const
{
  SetRow(OsFieldName(ostype)+"EXPORT_PATH",path);
}


QString RDReport::postExportCommand(ExportOs ostype) const
{
  return RDGetSqlValue("REPORTS","NAME",report_name,
		       OsFieldName(ostype)+"POST_EXPORT_CMD").toString();
}


void RDReport::setPostExportCommand(ExportOs ostype,const QString &cmd) const
{
  SetRow(OsFieldName(ostype)+"POST_EXPORT_CMD",cmd);
}


bool RDReport::exportTypeEnabled(ExportType type) const
{
  return RDBool(RDGetSqlValue("REPORTS","NAME",report_name,
			    TypeFieldName(type,false)).toString());
}


void RDReport::setExportTypeEnabled(ExportType type,bool state) const
{
  SetRow(TypeFieldName(type,false),RDYesNo(state));
}


bool RDReport::exportTypeForced(ExportType type) const
{
  return RDBool(RDGetSqlValue("REPORTS","NAME",report_name,
			    TypeFieldName(type,true)).toString());
}


void RDReport::setExportTypeForced(ExportType type,bool state) const
{
  SetRow(TypeFieldName(type,true),RDYesNo(state));
}


QString RDReport::stationId() const
{
  return RDGetSqlValue("REPORTS","NAME",report_name,"STATION_ID").toString();
}


void RDReport::setStationId(const QString &id) const
{
  SetRow("STATION_ID",id);
}


unsigned RDReport::cartDigits() const
{
  return RDGetSqlValue("REPORTS","NAME",report_name,"CART_DIGITS").toUInt();
}

  
void RDReport::setCartDigits(unsigned num) const
{
  SetRow("CART_DIGITS",num);
}


bool RDReport::useLeadingZeros() const
{
  return RDBool(RDGetSqlValue("REPORTS","NAME",report_name,"USE_LEADING_ZEROS").
	       toString());
}


void RDReport::setUseLeadingZeros(bool state) const
{
  SetRow("USE_LEADING_ZEROS",state);
}


int RDReport::linesPerPage() const
{
  return RDGetSqlValue("REPORTS","NAME",report_name,"LINES_PER_PAGE").toInt();
}


void RDReport::setLinesPerPage(int lines) const
{
  SetRow("LINES_PER_PAGE",lines);
}


QString RDReport::serviceName() const
{
  return RDGetSqlValue("REPORTS","NAME",report_name,"SERVICE_NAME").toString();
}


void RDReport::setServiceName(const QString &name) const
{
  SetRow("SERVICE_NAME",name);
}


RDReport::StationType RDReport::stationType() const
{
  return (RDReport::StationType)
    RDGetSqlValue("REPORTS","NAME",report_name,"STATION_TYPE").toInt();
}


void RDReport::setStationType(RDReport::StationType type) const
{
  SetRow("STATION_TYPE",(int)type);
}


QString RDReport::stationFormat() const
{
  return RDGetSqlValue("REPORTS","NAME",report_name,"STATION_FORMAT").
    toString();
}


void RDReport::setStationFormat(const QString &fmt) const
{
  SetRow("STATION_FORMAT",fmt);
}


bool RDReport::filterOnairFlag() const
{
  return RDBool(RDGetSqlValue("REPORTS","NAME",report_name,"FILTER_ONAIR_FLAG").
    toString());
}


void RDReport::setFilterOnairFlag(bool state) const
{
  SetRow("FILTER_ONAIR_FLAG",RDYesNo(state));
}


bool RDReport::filterGroups() const
{
  return RDBool(RDGetSqlValue("REPORTS","NAME",report_name,"FILTER_GROUPS").
    toString());
}


void RDReport::setFilterGroups(bool state) const
{
  SetRow("FILTER_GROUPS",RDYesNo(state));
}


QTime RDReport::startTime(bool *is_null) const
{
  if(is_null!=NULL) {
    if(RDIsSqlNull("REPORTS","NAME",report_name,"START_TIME")) {
      *is_null=true;
      return QTime();
    }
    *is_null=false;
  }
  return RDGetSqlValue("REPORTS","NAME",report_name,"START_TIME").toTime();
}


void RDReport::setStartTime(const QTime &time) const
{
  SetRow("START_TIME",time);
}


void RDReport::setStartTime() const
{
  SetRowNull("START_TIME");
}


QTime RDReport::endTime(bool *is_null) const
{
  if(is_null!=NULL) {
    if(RDIsSqlNull("REPORTS","NAME",report_name,"END_TIME")) {
      *is_null=true;
      return QTime();
    }
    *is_null=false;
  }
  return RDGetSqlValue("REPORTS","NAME",report_name,"END_TIME").toTime();
}



void RDReport::setEndTime(const QTime &time) const
{
  SetRow("END_TIME",time);
}


void RDReport::setEndTime() const
{
  SetRowNull("END_TIME");
}


bool RDReport::aggregateTuningHoursRequired() const
{
  return RDReport::aggregateTuningHoursRequired(filter());
}


RDReport::ErrorCode RDReport::errorCode() const
{
  return report_error_code;
}


bool RDReport::outputExists(const QDate &startdate)
{
  QString out_path;
  out_path=RDDateDecode(exportPath(RDReport::Linux),startdate,report_station,
			report_config,serviceName());
  return QFile::exists(out_path);
}


bool RDReport::generateReport(const QDate &startdate,const QDate &enddate,
			      RDStation *station,QString *out_path,double ath)
{
  QString sql;
  RDSqlQuery *q;
  RDSqlQuery *q1;
  RDSvc *svc;
  QString daypart_sql;
  QString station_sql;
  QString group_sql;
  QString force_sql;
  bool is_null=false;

  if(!exists()) {
    return false;
  }

  //
  // Generate the daypart filter
  //
  startTime(&is_null);
  if(!is_null) {
    for(int i=0;i<(startdate.daysTo(enddate)+1);i++) {
      QDate date=startdate.addDays(i);
      if(startTime()<endTime()) {
	daypart_sql+=QString("((`EVENT_DATETIME`>='")+
	  date.toString("yyyy-MM-dd")+
	  " "+startTime().toString("hh:mm:ss")+"')&&"+
	  "(`EVENT_DATETIME`<'"+date.toString("yyyy-MM-dd")+
	  " "+endTime().toString("hh:mm:ss")+"'))||";
      }
      else {
	daypart_sql+=QString("((`EVENT_DATETIME`<='")+
	  date.toString("yyyy-MM-dd")+
	  " "+endTime().toString("hh:mm:ss")+"')&&"+
	  "(`EVENT_DATETIME`>'"+date.toString("yyyy-MM-dd")+" 00:00:00))||"+
	  "((`EVENT_DATETIME`>='"+
	  date.toString("yyyy-MM-dd")+
	  " "+startTime().toString("hh:mm:ss")+"')&&"+
	  "(`EVENT_DATETIME`<'"+date.toString("yyyy-MM-dd")+" 23:59:59))||";
	
      }
    }
    daypart_sql=daypart_sql.left(daypart_sql.length()-2);
  }

  //
  // Generate the Station List
  //
  sql=QString("select `STATION_NAME` from `REPORT_STATIONS` where ")+
    "`REPORT_NAME`='"+RDEscapeString(name())+"'";
  q=new RDSqlQuery(sql);
  while(q->next()) {
    station_sql+=
      QString("(`STATION_NAME`='")+
      RDEscapeString(q->value(0).toString())+"')||";
  }
  delete q;
  station_sql=station_sql.left(station_sql.length()-2);

  //
  // Next, the group list
  //
  bool where=false;
  if(exportTypeEnabled(RDReport::Generic)) {
    sql="select `NAME` from `GROUPS`  ";
  }
  else {
    where=true;
    sql="select `NAME` from `GROUPS` where ";
    if(exportTypeEnabled(RDReport::Traffic)) {
      sql+="(`REPORT_TFC`='Y')||";
    }
    if(exportTypeEnabled(RDReport::Music)) {
      sql+="(`REPORT_MUS`='Y')||";
    }
  }
  if(filterGroups()) {
    QString sql2=QString("select `GROUP_NAME` from `REPORT_GROUPS` where ")+
      "`REPORT_NAME`='"+RDEscapeString(name())+"'";
    q=new RDSqlQuery(sql2);
    while(q->next()) {
      if(!where) {
	sql+="where ";
	where=true;
      }
      sql+=QString("(`NAME`='")+RDEscapeString(q->value(0).toString())+"')||";
    }
    delete q;
  }
  sql=sql.left(sql.length()-2);
  q=new RDSqlQuery(sql);
  while(q->next()) {
    group_sql+=QString("(`CART`.`GROUP_NAME`='")+
      RDEscapeString(q->value(0).toString())+"')||";
  }
  delete q;
  group_sql=group_sql.left(group_sql.length()-2);
  if(group_sql.length()==2) {
    group_sql="";
  }
  
  //
  // Generate Mixdown ID
  //
  QString mixname=QString::asprintf("MX%d",getpid());

  //
  // Iterate Selected Services
  //
  sql=QString("select `SERVICE_NAME` from `REPORT_SERVICES` where ")+
    "`REPORT_NAME`='"+RDEscapeString(name())+"'";
  q=new RDSqlQuery(sql);
  while(q->next()) {
    svc=new RDSvc(q->value(0).toString(),report_station,report_config);
    if(svc->exists()) {
      //
      // Generate Type Filters
      //
      force_sql="";
      if(!exportTypeEnabled(RDReport::Generic)) {
	if(exportTypeForced(RDReport::Traffic)||
	   exportTypeEnabled(RDReport::Traffic)) {
	  force_sql+=QString::asprintf("(`ELR_LINES`.`EVENT_SOURCE`=%d)||",
				       RDLogLine::Traffic);
	}
	if(exportTypeForced(RDReport::Music)||
	   exportTypeEnabled(RDReport::Music)) {
	  force_sql+=QString::asprintf("(`ELR_LINES`.`EVENT_SOURCE`=%d)||",
				       RDLogLine::Music);
	}
	force_sql=force_sql.left(force_sql.length()-2);
      }

      //
      // Selected Fields
      //
      sql=QString("select ")+
	"`LENGTH`,"+                    // 00
	"`LOG_ID`,"+                    // 01
	"`CART_NUMBER`,"+               // 02
	"`STATION_NAME`,"+              // 03
	"`EVENT_DATETIME`,"+            // 04
	"`EVENT_TYPE`,"+                // 05
	"`EXT_START_TIME`,"+            // 06
	"`EXT_LENGTH`,"+                // 07
	"`EXT_DATA`,"+                  // 08
	"`EXT_EVENT_ID`,"+              // 09
	"`EXT_ANNC_TYPE`,"+             // 10
	"`PLAY_SOURCE`,"+               // 11
	"`CUT_NUMBER`,"+                // 12
	"`EVENT_SOURCE`,"+              // 13
	"`EXT_CART_NAME`,"+             // 14
	"`LOG_NAME`,"+                  // 15
	"`ELR_LINES`.`TITLE`,"+         // 16
	"`ELR_LINES`.`ARTIST`,"+        // 17
	"`SCHEDULED_TIME`,"+            // 18
	"`START_SOURCE`,"+             // 19
	"`ELR_LINES`.`PUBLISHER`,"+     // 20
	"`ELR_LINES`.`COMPOSER`,"+      // 21
	"`ELR_LINES`.`ALBUM`,"+         // 22
	"`ELR_LINES`.`LABEL`,"+         // 23
	"`ELR_LINES`.`ISRC`,"+          // 24
	"`ELR_LINES`.`USAGE_CODE`,"+    // 25
	"`ELR_LINES`.`ONAIR_FLAG`,"+    // 26
	"`ELR_LINES`.`ISCI`,"+          // 27
	"`ELR_LINES`.`CONDUCTOR`,"+     // 28
	"`ELR_LINES`.`USER_DEFINED`,"+  // 29
	"`ELR_LINES`.`SONG_ID`,"+       // 30
	"`ELR_LINES`.`DESCRIPTION`,"+   // 31
	"`ELR_LINES`.`OUTCUE` "+        // 32
	"from `ELR_LINES` left join `CART` "+
	"on `ELR_LINES`.`CART_NUMBER`=`CART`.`NUMBER` where "+
	"`SERVICE_NAME`='"+RDEscapeString(q->value(0).toString())+"' && ";

      //
      // OnAir Flag Filter
      //
      if(filterOnairFlag()) {
	sql+="(`ONAIR_FLAG`='Y')&&";
      }

      //
      // Group Filter
      //
      sql+="(";
      if(!group_sql.isEmpty()) {
	sql+=QString("(")+group_sql+")&&";
      }
      if(!force_sql.isEmpty()) {
	sql+=QString("(")+force_sql+")&&";
      }

      //
      // Daypart Filter
      //
      if(daypart_sql.isEmpty()) {
    	  //TODO Do we need to escape on Select statement?
	sql+=QString("(`EVENT_DATETIME`>='")+startdate.toString("yyyy-MM-dd")+
	  " 00:00:00')&&"+
	  "(`EVENT_DATETIME`<='"+enddate.toString("yyyy-MM-dd")+
	  " 23:59:59')&&";
      }
      else {
	sql+=(QString("(")+daypart_sql+")&&");
      }
      if(!station_sql.isEmpty()) {
	sql+=QString("(")+station_sql+")||";
      }
      sql=sql.left(sql.length()-2);
      sql+=")";
      q1=new RDSqlQuery(sql);
      while(q1->next()) {
	sql=QString("insert into `ELR_LINES` set ")+
	  "`SERVICE_NAME`='"+RDEscapeString(mixname)+"',"+
	  QString::asprintf("`LENGTH`=%d,`LOG_ID`=%u,`CART_NUMBER`=%u,",
			    q1->value(0).toInt(),
			    q1->value(1).toUInt(),
			    q1->value(2).toInt())+
	  "`STATION_NAME`='"+RDEscapeString(q1->value(3).toString())+"',"+
	  "`EVENT_DATETIME`="+RDCheckDateTime(q1->value(4).toDateTime(),
					      "yyyy-MM-dd hh:mm:ss")+","+
	  QString::asprintf("`EVENT_TYPE`=%d,",q1->value(5).toInt())+
	  "`EXT_START_TIME`="+
	  RDCheckDateTime(q1->value(6).toTime(),"hh:mm:ss")+","+
	  QString::asprintf("`EXT_LENGTH`=%d,",q1->value(7).toInt())+
	  "`EXT_DATA`='"+RDEscapeString(q1->value(8).toString())+"',"+
	  "`EXT_EVENT_ID`='"+RDEscapeString(q1->value(9).toString())+"',"+
	  "`EXT_ANNC_TYPE`='"+RDEscapeString(q1->value(10).toString())+"',"+
	  QString::asprintf("`PLAY_SOURCE`=%d,",q1->value(11).toInt())+
	  QString::asprintf("`CUT_NUMBER`=%d,",q1->value(12).toInt())+
	  QString::asprintf("`EVENT_SOURCE`=%d,",q1->value(13).toInt())+
	  "`EXT_CART_NAME`='"+RDEscapeString(q1->value(14).toString())+"',"+
	  "`LOG_NAME`='"+RDEscapeString(q1->value(15).toString())+"',"+
	  "`TITLE`='"+RDEscapeString(q1->value(16).toString())+"',"+
	  "`ARTIST`='"+RDEscapeString(q1->value(17).toString())+"',"+
	  "`SCHEDULED_TIME`="+
	  RDCheckDateTime(q1->value(18).toDate(),"yyyy-MM-dd hh:mm:ss")+","+
	  QString::asprintf("`START_SOURCE`=%d,",q1->value(19).toInt())+
	  "`PUBLISHER`='"+RDEscapeString(q1->value(20).toString())+"',"+
	  "`COMPOSER`='"+RDEscapeString(q1->value(21).toString())+"',"+
	  "`ALBUM`='"+RDEscapeString(q1->value(22).toString())+"',"+
	  "`LABEL`='"+RDEscapeString(q1->value(23).toString())+"',"+
	  "`ISRC`='"+RDEscapeString(q1->value(24).toString())+"',"+
	  QString::asprintf("`USAGE_CODE`=%d,",q1->value(25).toInt())+
	  "`ONAIR_FLAG`='"+RDEscapeString(q1->value(26).toString())+"',"+
	  "`ISCI`='"+RDEscapeString(q1->value(27).toString())+"',"+
	  "`CONDUCTOR`='"+RDEscapeString(q1->value(28).toString())+"',"+
	  "`USER_DEFINED`='"+RDEscapeString(q1->value(29).toString())+"',"+
	  "`SONG_ID`='"+RDEscapeString(q1->value(30).toString())+"',"+
	  "`DESCRIPTION`='"+RDEscapeString(q1->value(31).toString())+"',"+
	  "`OUTCUE`='"+RDEscapeString(q1->value(32).toString())+"'";
	RDSqlQuery::apply(sql);
      }
      delete q1;
    }
    delete svc;
  }
  delete q;

  bool ret=false;
  QString filename=RDDateDecode(exportPath(RDReport::Linux),startdate,
				report_station,report_config,serviceName());
  switch(filter()) {
  case RDReport::CbsiDeltaFlex:
    ret=ExportDeltaflex(filename,startdate,enddate,mixname);
    break;

  case RDReport::TextLog:
    ret=ExportTextLog(filename,startdate,enddate,mixname);
    break;

  case RDReport::BmiEmr:
    ret=ExportBmiEmr(filename,startdate,enddate,mixname);
    break;

  case RDReport::NaturalLog:
  case RDReport::Technical:
    ret=ExportTechnical(filename,startdate,enddate,true,false,mixname);
    break;

  case RDReport::SoundExchange:
    ret=ExportSoundEx(filename,startdate,enddate,ath,mixname);
    break;

  case RDReport::NprSoundExchange:
    ret=ExportNprSoundEx(filename,startdate,enddate,mixname);
    break;

  case RDReport::RadioTraffic:
    ret=ExportRadioTraffic(filename,startdate,enddate,mixname,0);
    break;

  case RDReport::RadioTraffic2:
    ret=ExportRadioTraffic(filename,startdate,enddate,mixname,1);
    break;

  case RDReport::VisualTraffic:
    ret=ExportDeltaflex(filename,startdate,enddate,mixname);
    break;

  case RDReport::CounterPoint:
  case RDReport::WideOrbit:
    ret=ExportRadioTraffic(filename,startdate,enddate,mixname,0);
    break;

  case RDReport::CounterPoint2:
    ret=ExportRadioTraffic(filename,startdate,enddate,mixname,1);
    break;

  case RDReport::Music1:
    ret=ExportRadioTraffic(filename,startdate,enddate,mixname,0);
    break;

  case RDReport::MusicClassical:
    ret=ExportMusicClassical(filename,startdate,enddate,mixname);
    break;

  case RDReport::MusicPlayout:
    ret=ExportMusicPlayout(filename,startdate,enddate,mixname);
    break;

  case RDReport::SpinCount:
    ret=ExportSpinCount(filename,startdate,enddate,mixname);
    break;

  case RDReport::MusicSummary:
    ret=ExportMusicSummary(filename,startdate,enddate,mixname);
    break;

  case RDReport::MrMaster:
    ret=ExportTechnical(filename,startdate,enddate,false,true,mixname);
    break;

  case RDReport::CutLog:
    ret=ExportCutLog(filename,startdate,enddate,mixname);
    break;

  case RDReport::ResultsReport:
    ret=ExportResultsReport(filename,startdate,enddate,mixname);
    break;

  default:
    return false;
    break;
  }
  *out_path=RDDateDecode(exportPath(RDReport::Linux),startdate,report_station,
			 report_config,serviceName());
  QString post_cmd=RDDateDecode(postExportCommand(RDReport::Linux),startdate,
				report_station,report_config,serviceName());
  RDCheckExitCode("RDReport::generateReport system",system(post_cmd.toUtf8()));

  sql=QString("delete from `ELR_LINES` where ")+
    "`SERVICE_NAME`='"+RDEscapeString(mixname)+"'";
  RDSqlQuery::apply(sql);

  //  printf("RDReport mixname: %s\n",mixname.toUtf8().constData());

  return ret;
}


QString RDReport::filterText(RDReport::ExportFilter filter)
{
  switch(filter) {
  case RDReport::CbsiDeltaFlex:
    return QObject::tr("CBSI DeltaFlex Traffic Reconciliation v2.01");

  case RDReport::TextLog:
    return QObject::tr("Text Log");

  case RDReport::BmiEmr:
    return QObject::tr("ASCAP/BMI Electronic Music Report");

  case RDReport::Technical:
    return QObject::tr("Technical Playout Report");

  case RDReport::SoundExchange:
    return QObject::tr("SoundExchange Statutory License Report");

  case RDReport::NprSoundExchange:
    return QObject::tr("NPR/DS SoundExchange Report");

  case RDReport::RadioTraffic:
    return QObject::tr("Original RadioTraffic.com Traffic Reconciliation (DEPRECATED)");

  case RDReport::RadioTraffic2:
    return QObject::tr("RadioTraffic.com Traffic Reconciliation");

  case RDReport::VisualTraffic:
    return QObject::tr("VisualTraffic Reconciliation");

  case RDReport::CounterPoint:
    return QObject::tr("CounterPoint Traffic Reconciliation");

  case RDReport::CounterPoint2:
    return QObject::tr("CounterPoint Traffic Reconciliation v2");

  case RDReport::MrMaster:
    return QObject::tr("Mr. Master Reconciliation");

  case RDReport::Music1:
    return QObject::tr("Music1 Reconciliation");

  case RDReport::MusicClassical:
    return QObject::tr("Classical Music Playout");

  case RDReport::MusicPlayout:
    return QObject::tr("Music Playout");

  case RDReport::MusicSummary:
    return QObject::tr("Music Summary");

  case RDReport::NaturalLog:
    return QObject::tr("NaturalLog Reconciliation");

  case RDReport::SpinCount:
    return QObject::tr("Spin Count");

  case RDReport::WideOrbit:
    return QObject::tr("WideOrbit Traffic Reconciliation");

  case RDReport::CutLog:
    return QObject::tr("Cut Log");

  case RDReport::ResultsReport:
    return QObject::tr("Results Report");

  case RDReport::LastFilter:
    break;
  }

  return QObject::tr("Unknown");
}


QString RDReport::stationTypeText(RDReport::StationType type)
{
  switch(type) {
  case RDReport::TypeOther:
    return QObject::tr("Other");

  case RDReport::TypeAm:
    return QObject::tr("AM");

  case RDReport::TypeFm:
    return QObject::tr("FM");

  default:
    break;
  }
  return QObject::tr("Unknown");
}


bool RDReport::multipleDaysAllowed(RDReport::ExportFilter filter)
{
  switch(filter) {
  case RDReport::CbsiDeltaFlex:
  case RDReport::TextLog:
  case RDReport::RadioTraffic:
  case RDReport::RadioTraffic2:
  case RDReport::VisualTraffic:
  case RDReport::CounterPoint:
  case RDReport::CounterPoint2:
  case RDReport::LastFilter:
  case RDReport::MrMaster:
  case RDReport::Music1:
  case RDReport::MusicClassical:
  case RDReport::MusicPlayout:
  case RDReport::NaturalLog:
  case RDReport::SpinCount:
  case RDReport::WideOrbit:
  case RDReport::CutLog:
  case RDReport::ResultsReport:
    return false;

  case RDReport::BmiEmr:
  case RDReport::MusicSummary:
  case RDReport::NprSoundExchange:
  case RDReport::SoundExchange:
  case RDReport::Technical:
    return true;
  }
  return true;
}


bool RDReport::multipleMonthsAllowed(RDReport::ExportFilter filter)
{
  switch(filter) {
  case RDReport::CbsiDeltaFlex:
  case RDReport::TextLog:
  case RDReport::BmiEmr:
  case RDReport::RadioTraffic:
  case RDReport::RadioTraffic2:
  case RDReport::VisualTraffic:
  case RDReport::CounterPoint:
  case RDReport::CounterPoint2:
  case RDReport::LastFilter:
  case RDReport::MrMaster:
  case RDReport::Music1:
  case RDReport::MusicClassical:
  case RDReport::MusicPlayout:
  case RDReport::NaturalLog:
  case RDReport::WideOrbit:
  case RDReport::CutLog:
  case RDReport::ResultsReport:
    return false;
    
  case RDReport::MusicSummary:
  case RDReport::NprSoundExchange:
  case RDReport::SoundExchange:
  case RDReport::SpinCount:
  case RDReport::Technical:
    return true;
  }
  return true;
}


bool RDReport::aggregateTuningHoursRequired(RDReport::ExportFilter filter)
{
  bool ret=false;

  switch(filter) {
  case RDReport::CbsiDeltaFlex:
  case RDReport::TextLog:
  case RDReport::BmiEmr:
  case RDReport::RadioTraffic:
  case RDReport::RadioTraffic2:
  case RDReport::VisualTraffic:
  case RDReport::CounterPoint:
  case RDReport::CounterPoint2:
  case RDReport::MrMaster:
  case RDReport::Music1:
  case RDReport::MusicClassical:
  case RDReport::MusicPlayout:
  case RDReport::NaturalLog:
  case RDReport::WideOrbit:
  case RDReport::CutLog:
  case RDReport::ResultsReport:
  case RDReport::MusicSummary:
  case RDReport::NprSoundExchange:
  case RDReport::SpinCount:
  case RDReport::Technical:
  case RDReport::LastFilter:
    ret=false;
    break;

  case RDReport::SoundExchange:
    ret=true;
    break;
  }

  return ret;
}

QString RDReport::errorText(RDReport::ErrorCode code)
{
  QString ret;
  switch(code) {
      case RDReport::ErrorOk:
	ret=QObject::tr("Report complete!");
	break;

      case RDReport::ErrorCanceled:
	ret=QObject::tr("Report canceled!");
	break;

      case RDReport::ErrorCantOpen:
	ret=QObject::tr("Unable to open report file!");
	break;
  }
  return ret;
}


QString RDReport::leftJustify(const QString &str,int width)
{
  QString ret=str.left(width);

  while(ret.length()<width) {
    ret+=" ";
  }

  return ret;
}


QString RDReport::rightJustify(const QString &str,int width)
{
  QString ret=str.left(width);

  while(ret.length()<width) {
    ret=" "+ret;
  }

  return ret;
}


QString RDReport::center(const QString &str,int width)
{
  QString ret=str.left(width);

  int margin=(width-ret.length())/2;
  for(int i=0;i<margin;i++) {
    ret=" "+ret;
  }
  return ret;
}


void RDReport::SetRow(const QString &param,const QString &value) const
{
  QString sql;

  sql=QString("update `REPORTS` set `")+
    param+"`='"+RDEscapeString(value)+"' where "+
    "`NAME`='"+RDEscapeString(report_name)+"'";
  RDSqlQuery::apply(sql);
}


void RDReport::SetRow(const QString &param,int value) const
{
  QString sql;

  sql=QString("update `REPORTS` set `")+
    param+QString::asprintf("`=%d where ",value)+
    "`NAME`='"+RDEscapeString(report_name)+"'";
  RDSqlQuery::apply(sql);
}


void RDReport::SetRow(const QString &param,unsigned value) const
{
  QString sql;

  sql=QString("update `REPORTS` set `")+
    param+QString::asprintf("`=%u where ",value)+
    "`NAME`='"+RDEscapeString(report_name)+"'";
  RDSqlQuery::apply(sql);
}


void RDReport::SetRow(const QString &param,bool value) const
{
  QString sql;

  sql=QString("update `REPORTS` set `")+
    param+"`='"+RDYesNo(value)+"' where "+
    "`NAME`='"+RDEscapeString(report_name)+"'";
  RDSqlQuery::apply(sql);
}


void RDReport::SetRow(const QString &param,const QTime &value) const
{
  RDSqlQuery *q;
  QString sql;

  sql=QString("update REPORTS set ")+
    param+"="+RDCheckDateTime(value, "hh:mm:ss")+" where "+
    "NAME=\""+RDEscapeString(report_name)+"\"";
  q=new RDSqlQuery(sql);
  delete q;
}


void RDReport::SetRowNull(const QString &param) const
{
  RDSqlQuery *q;
  QString sql;

  sql=QString("update REPORTS set ")+param+"=NULL where NAME=\""+
    RDEscapeString(report_name)+"\"";
  q=new RDSqlQuery(sql);
  delete q;
}


QString RDReport::OsFieldName(ExportOs os) const
{
  switch(os) {
      case RDReport::Linux:
	return QString("");
	
      case RDReport::Windows:
	return QString("WIN_");
  }
  return QString();
}


QString RDReport::TypeFieldName(ExportType type,bool forced) const
{
  if(forced) {
    switch(type) {
	case RDReport::Traffic:
	  return QString("FORCE_TFC");
	  
	case RDReport::Music:
	  return QString("FORCE_MUS");

	default:
	  return QString();
    }
  }
  else {
    switch(type) {
	case RDReport::Generic:
	  return QString("EXPORT_GEN");
	  
	case RDReport::Traffic:
	  return QString("EXPORT_TFC");
	  
	case RDReport::Music:
	  return QString("EXPORT_MUS");
    }
    return QString();
  }
  return QString();
}