#
# == epcb/data
# ExcelPettyCashBookコマンドラインツールが内部的に使用するデータクラスを集めたファイル。
# 
# Revision:: $Id$
#
module EPCB
  # マスタシート名
  MASTER_SHEET_NAME = "マスタ"
  # プリファレンスシート名
  PREFS_SHEET_NAME = "PREFS"

  #
  # Excelの"収入/支出データ"の1行分のエントリを表すデータクラス。
  #
  class IncomeExpensesData ; end

  #
  # 1.0用IncomeExpensesData。
  #
  class IncomeExpensesData_1_0
    attr_accessor :date, :use, :amount_of_money, :note

    # コンストラクタ。
    # === ARGS
    # date:: 日付
    # use:: 用途
    # amount_of_money:: 金額
    def initialize(date = nil, use = nil, amount_of_money = nil, note = nil)
      @date = date
      @use = use
      @amount_of_money = amount_of_money
      @note = note
    end

    # Excel上のカラム順でデータを格納した配列を返す。
    def to_a
      return [ @date, @use, @amount_of_money, @note ]
    end

    def inspect
      return to_a.inspect
    end
  end #IncomeExpensesData_1_0#

  #
  # 用途マスタを表すクラス。
  #
  class UseMasterData
    attr_accessor :value, :note

    # コンストラクタ
    # === ARGS
    # value:: "食費"などの値
    # note:: 備考(2005/04/28現在使用されていない)
    def initialize(value = nil, note = nil)
      @value = value
      @note = note
    end
  end

  #
  # 1.1用IncomeExpensesData。定義のみ。
  #
  class IncomeExpensesData_1_1 < IncomeExpensesData_1_0 ; end

  #
  # 1.2用IncomeExpensesData。定義のみ。
  #
  class IncomeExpensesData_1_2 < IncomeExpensesData_1_1 ; end

  #
  # Excelのシートを表すモジュール。
  #
  module NamedDataSet
    include Enumerable
    attr_reader :name
    @name = nil
    @data = Array.new

    # マスタデータを格納しているNamedDataSetかどうか判定する。
    # この実装では常にfalseを返す。
    # === RETURNS
    # マスタデータを格納している場合はtrue
    def master?
      return false
    end

    # プリファレンスを格納しているNamedDataSetかどうか判定する。
    # この実装では常にfalseを返す。
    # === RETURNS
    # プリファレンスを格納している場合はtrue
    def prefs?
      return false
    end

    # 1レコード分のデータをこのNamedDataSetに追加する。
    # === ARGS
    # data:: 1行分のデータ
    def add(data)
      @data << data
    end

    # このオブジェクトが持つデータ行の数を返す。
    # === RETURNS
    # データ行の数
    def size
      return @data.size
    end

    # このオブジェクトが格納しているデータを全てたどる。
    def each
      @data.each do |d|
        yield(d)
      end
    end
  end #NamedDataSet#

  #
  # ExcelPettyCashBookの1か月分のデータを表すクラス(Excelのデータシート1個に相当)。
  # IncomeExpensesDataを格納する。
  #
  class MonthData
    include NamedDataSet

    # コンストラクタ。
    # === ARGS
    # name:: シート名
    def initialize(name)
      @name = name
      @data = Array.new
    end
  end #MonthData#

  #
  # ExcelPettyCashBookのマスタデータクラス(Excelのマスタシートを表す)。
  #
  class MasterData
    include NamedDataSet
    attr_accessor :use

    # コンストラクタ。
    def initialize
      @name = MASTER_SHEET_NAME
      @use = Array.new
    end
    
    # 常にtrueを返す。
    def master?
      return true
    end

    # 何もしない
    def add(data) ; end

    # このマスタシートが持つマスタの数を返す。
    def size
      return to_a.size
    end

    # "用途マスタ"のデータを全てたどる。
    # ブロックの引数はUseMasterData型である。
    def each_use
      @use.each do |d|
        yield(d)
      end
    end

    def to_a
      return [ @use ]
    end
  end #MasterData#

  class PreferencesData
    include NamedDataSet

    def initialize
      @name = PREFS_SHEET_NAME
      @data = Hash.new
    end

    def store(name, value)
      return if name.nil? || name == ""
      @data.store(name, value)
    end

    # 常にtrueを返す。
    def prefs?
      return true
    end

    def add(data) ; end

    def each
      @data.each_pair do |name, value|
        yield(name, value)
      end
    end
  end #PreferencesData#
end


