# program_admin.rb

# $Id: program_admin.rb,v 1.2 2002/05/04 16:21:31 hasimoto_fukui Exp $

# 2002/4/30  Takuro Ashie <ashie@homa.ne.jp>
# Copyright (C) 2002 Takuro Ashie <ashie@homa.ne.jp>
# This is free software with ABSOLUTELY NO WARRANTY.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


require 'program_item'

ProgramListFile = "#{VideoRecordingVarDir}/program_list"
ChannelListFile = "#{VideoRecordingConfDir}/channel_table.conf"


###############################################################################
#
#   ProgramAdmin Class
#
###############################################################################
class ProgramAdmin

  #
  # initialize ()
  #
  def initialize ()
    @program_list = nil  # Array (ProgramItem)
    @channel_list = nil  # Array (String)
    @quality_list = nil  # Array (String)

    @channel_hash = nil  # Hash (String, String)

    loadChannelItems
    loadQualityItems
    loadList
  end

  attr_reader :program_list
  attr_reader :channel_list
  attr_reader :quality_list


  #
  # loadList () :
  #    Read program list from file, and store it to @program_list.
  #    If list is already exist, it will be cleared first.
  #
  # Return : New array of ProgramItem.
  #
  def loadList ()

    if @program_list then
      @program_list.clear
    end

    @program_list = Array.new

    open(ProgramListFile) do |file|
      file.each do |line|
        next unless (line =~ /.+\s+.+\s+.+\s+.+\s+.+\s+.+\s+.+/)

        item = ProgramItem.new
        ary = line.chomp.split (/\s+/)

        ymd = ary[0].split (/\//)
        hms = ary[1].split (/:/)
        item.starttime = Time.local(ymd[0], ymd[1], ymd[2],
                                    hms[0], hms[1], hms[2]);

        ymd = ary[2].split (/\//)
        hms = ary[3].split (/:/)
        item.endtime = Time.local(ymd[0], ymd[1], ymd[2],
                                  hms[0], hms[1], hms[2]);

        item.channel = ary[4]
        item.quality = ary[5]
        item.filename= ary[6]

        if item.valid? then
          @program_list << item
        end
      end
    end

    @program_list.sort! { |a,b| a.starttime<=>b.starttime }
  end


  #
  # include? () :
  #    Check for same program.
  #
  # aProgram : The ProgramItem to check duplicates.
  # Return   : true if found.
  #
  def include? (aProgram)
    loadList ()
    return @program_list.include? (aProgram)
  end


  #
  # doubleBooking? () :
  #    Check whether the program time zone is overlaping to this or not.
  #
  # program   : The ProgramItem to compare.
  # skip_same : Ignore same item to aProgram if this value is true.
  # Return    : ture if exists.
  #
  def doubleBooking? (program, skip_same = false)
    loadList ()

    @program_list.each do |item|
      if !skip_same && item == program then
        return true
      end

      if item.doubleBooking? (program) then
        return true
      end
    end

    return false
  end


  #
  # << () :
  #    Add a new ProgramItem to the list.
  #
  # program : The ProgramItem to add.
  # Return  : New array of ProgramItem.
  #
  def << (program)
    loadList ()

    # validate
    if !program.valid? then
      return @program_list
    end

    # check duplicates
    if doubleBooking? (program) then
      return @program_list
    end

    @program_list << program
    @program_list.sort! { |a,b| a.starttime<=>b.starttime }

    write ()

    return @program_list
  end

  alias add <<
  alias add_program <<


  #
  # delete () :
  #    Delete a ProgramItem
  #
  # aProgram : The ProgramItem to delete
  # Return   : New array of ProgramItem.
  #
  def delete (aProgram)
    loadList ()
    item = @program_list.delete (aProgram)
    if item then
      write ()
    end
    return @program_list
  end

  alias del delete
  alias delete_program delete


  #
  # update_program () :
  #
  # aSrc    :
  # aDest   :
  # Return  : New array of program items.
  #
  def updateProgram (aDest, aSrc)
    p "not implemented yet"
  end


 private

  #
  # write () :
  #    Write program items list to the file.
  #
  def write ()
    if !@program_list then
      return
    end

    file = open(ProgramListFile, "w")
    @program_list.each do |item|
      stime = item.starttime.strftime ('%Y/%m/%d %H:%M:%S')
      etime = item.endtime.strftime ('%Y/%m/%d %H:%M:%S')
      file.print("#{stime} #{etime} #{item.channel} #{item.quality} #{item.filename}\n")
    end
    file.close
  end


  #
  # loadChannelItems () :
  #    Read channel list and store values to @channel_list
  #
  def loadChannelItems ()

    @channel_list = nil
    @channel_hash = nil

    if !File.exist? (ChannelListFile) then
      return
    end

    begin
      file = open(ChannelListFile)

      @channel_list = Array.new
      @channel_hash = Hash.new

      file.each do |line|
        next unless (line =~ /(\d+)\s+(\d+)/)

        ary = line.chomp.split(/\s+/)

        @channel_list << ary[0]
        @channel_hash[ary[0]] = ary[1]
      end

      file.close

    rescue
      fprintf STDERR, "Cannot open channel file: %s\n", ChannelListFile
      @channel_list = nil
      @channel_hash = nil
    end
  end


  #
  # loadQualityItems ()
  #    Store quality list to @quality_list.
  #
  def loadQualityItems ()
    @quality_list = ['VeryHighQ', 'HighQ', 'NormalQ', 'LowQ', 'VeryLowQ']
  end
end
