#
# == epcb/excel-serializer
#
# Revision:: $Id$
#
require 'fileutils'
require 'cli'

module EPCB
  #
  # SheetDataをExcelPettyCashBookのシートとして出力するSerializer。
  #
  class ExcelSerializer
    # コンストラクタ。
    # === ARGS
    # workbook:: シートを出力するExcelPettyCashBookのワークブック
    # eutil:: ExcelUtilインスタンス
    def initialize(workbook, eutil)
      @workbook = workbook
      @eutil = eutil
      ver = @eutil.version_from_workbook
      ver = EPCB::TARGET_VERSION if ver.nil?
      Log::voutln("output version = #{ver}")
      @feature = EPCB::new_feature(@eutil, ver, true)
      @offsets = [
        @feature.const_of("DATE_OFFSET").to_i,
        @feature.const_of("USE_OFFSET").to_i,
        @feature.const_of("AMOUNT_OF_MONEY_OFFSET").to_i,
        @feature.const_of("NOTE_OFFSET").to_i,
      ]
    end

    # 引数 +data_set+ をコンストラクタで与えられたワークブックに出力する。
    # === ARGS
    # data_set:: 出力するシートのデータ
    def serialize(data_set)
      Log::voutln("Serializing sheet \"#{data_set.name}\"")
      if data_set.master?
        serialize_master(data_set)
      elsif data_set.prefs?
        serialize_prefs(data_set)
      else
        serialize_data(data_set)
      end
      Log::voutln("Finished to serialize sheet \"#{data_set.name}\"\n")
    end

    protected
    def serialize_data(data_set)
      # 出力先のシートを作成
      sheet = @eutil.excel.run("CreateNewDataSheet", data_set.name, false)
      if sheet.nil?
        Log::eoutln("Couldn't create sheet \"#{data_set.name}\"." \
                    " but the process will go on.")
        return
      end

      Log::voutln("Created sheet \"#{sheet.name}\"")
      # シートをアクティブにしてInitializeマクロを呼ぶ
      sheet.activate
      @eutil.initialize_on_active_sheet
      
      line_pos = 0
      # データ行を全て調べる
      data_set.each do |data|
        # カラムを全て調べる
        i = 0
        data.to_a.each do |value|
          if value.nil?
            i += 1
            next
          end
          Log::debugln("get_offset(#{line_pos}, #{@offsets[i]}) = #{value} ")
          @eutil.get_offset(line_pos, @offsets[i]).value = value
          i += 1
        end
        line_pos += 1
        Log::debugln
      end
    end

    def serialize_master(data_set)
      sheet = @feature.get_master_sheet(@workbook)
      # ExcelPettyCashBookにマスタシートがない場合
      if sheet.nil?
        Log::voutln("Master sheet not found.")
        next
      end

      for i in 0 .. data_set.use.size - 1
        #Log::vout("cells(#{i+1}, 1) ")
        sheet.cells(i + 1, 1).value = data_set.use[i].value
      end

      # 移行先ファイルのマスタデータを空文字列で上書き
      for i in data_set.use.size + 1 .. @feature.const_of("MAX_DATA_LINE")
        sheet.cells(i, 1).value = ""
      end
      Log::voutln("Updated \"#{data_set.name}\".")
    end

    def serialize_prefs(data_set)
      sheet = @feature.get_prefs_sheet(@workbook)
      # ExcelPettyCashBookにプリファレンスシートがない場合
      if sheet.nil?
        Log::voutln("Prefs sheet not found.")
        return
      end
      
      # プリファレンスの内容をワークブックに保存
      data_set.each do |name, value|
        Log::debugln("prefs = { #{name} = #{value} }")
        @feature.put_preference(name, value)
      end

      # アクションフォームの位置を更新するマクロを呼び出す
      @feature.update_action_form_location

      Log::voutln("Updated \"#{data_set.name}\".")
    end
  end #ExcelSerializer#

end
