#! /usr/bin/env ruby -Ku
#
# 2008-04-17 katoy
#
# http://www.fsa.go.jp/singi/edinet/20080208.html
#  の xls ファイルを シート(業種)毎 に CSV ファイルで保存した。
#
# その CSV ファイルを読込み、利用する例である。
# XBRL インスタンスファイルの情報を
#   項目名(prefix:nake) -> 日本語名称ラベルに変換
# するのに利用できる。
# また、項目の表示順序、計算関係も取得できる。

require 'rubygems'
require 'fastercsv'
require 'kconv'

$KCODE="utf8"

# csv ファイルの "depth" のカラム位置 (0オリジン)
DEPTH_INDEX = 22

class EdinetTaxonomyInfo

  # EDINET Taxonomy の URL から業種ID を得る。
  @@URL2KIND = {
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/cte/" => :cte,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/cns/" => :cns,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/ves/" => :ves,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/bk1/" => :bk1,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/bk2/" => :bk2,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/cna/" => :cna,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/sec/" => :sec,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/in1/" => :in1,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/in2/" => :in2,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/rwy/" => :rwy,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/wat/" => :wat,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/hwy/" => :hwy,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/elc/" => :elc,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/ele/" => :ele,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/gas/" => :gas,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/liq/" => :liq,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/ivt/" => :ivt,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/inb/" => :inb,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/spf/" => :spf,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/med/" => :med,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/edu/" => :edu,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/cmd/" => :cmd,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/lea/" => :lea,
    "http://info.edinet-fsa.go.jp/jp/fr/gaap/r/fnd/" => :fnd,
  }

  # 業種ID から、csv ファイルパスを得る
  @@KIND2CSV = {
    :cte => "../edinet-2008-02-01/02-01.csv",  #  1 一般商工業 cte
    :cns => "../edinet-2008-02-01/02-02.csv",  #  2 建設業 cns
    :ves => "../edinet-2008-02-01/02-03.csv",  #  3 造船業 ves
    :bk1 => "../edinet-2008-02-01/02-04.csv",  #  4 銀行・信託業 bk1
    :bk2 => "../edinet-2008-02-01/02-05.csv",  #  5 銀行・信託業 (特定取引勘定設置銀行) bk2
    :cna => "../edinet-2008-02-01/02-06.csv",  #  6 建設保証業 cna
    :sec => "../edinet-2008-02-01/02-07.csv",  #  7 第一種金融商品取引業 sec
    :in1 => "../edinet-2008-02-01/02-08.csv",  #  8 生命保険業 in1
    :in2 => "../edinet-2008-02-01/02-09.csv",  #  9 損害保険業 in2
    :rwy => "../edinet-2008-02-01/02-10.csv",  # 10 鉄道事業 rwy
    :wat => "../edinet-2008-02-01/02-11.csv",  # 11 海運事業 wat
    :hwy => "../edinet-2008-02-01/02-12.csv",  # 12 高速道路事業 hwy
    :elc => "../edinet-2008-02-01/02-13.csv",  # 13 電気通信事業 elc
    :ele => "../edinet-2008-02-01/02-14.csv",  # 14 電気事業 ele
    :gas => "../edinet-2008-02-01/02-15.csv",  # 15 ガス事業 gas
    :liq => "../edinet-2008-02-01/02-16.csv",  # 16 資産流動化業 liq
    :ivt => "../edinet-2008-02-01/02-17.csv",  # 17 投資運用業 ivt
    :inb => "../edinet-2008-02-01/02-18.csv",  # 18 投資業 inv
    :spf => "../edinet-2008-02-01/02-19.csv",  # 19 特定金融業 spf
    :med => "../edinet-2008-02-01/02-20.csv",  # 20 社会医療法人 med
    :edu => "../edinet-2008-02-01/02-21.csv",  # 21 学校法人 edu
    :cmd => "../edinet-2008-02-01/02-22.csv",  # 22 商品先物取引業 cmd
    :lea => "../edinet-2008-02-01/02-23.csv",  # 23 リース事業 lea
    :fnd => "../edinet-2008-02-01/02-24.csv",  # 24 投資信託受益証券 fnd
  }

  def self.url2kind(url)
    @@URL2KIND[url[0..45]] # 45: @@URL2KIND の key の文字列長さ
  end

  def self.load(kind)
    taxonomyinfo = TaxonomyInfo.new
    taxonomyinfo.read_taxonomylinfo(@@KIND2CSV[kind])
    taxonomyinfo
  end
end

class TaxonomyInfo
  attr_reader :csv
  attr_reader :sheets, :labels

  def read_taxonomylinfo(csvFile)
    @csv = csvFile
    rows = FasterCSV.read(csvFile)

    @sheets = []
    @labels = {}

    sheet, sheet_name, sheet_title, sheet_labels = nil, nil, nil, nil

    status = nil
    rows.each { |row|
      status = get_status(row[DEPTH_INDEX])
      if status == :sheet
        if sheet != nil
          @sheets << {:name => sheet_name, :title => sheet_title, :labels => sheet_labels}
        end

        sheet = {}
        sheet_name = row[0]
        sheet_title = {}
        sheet_labels = []
      elsif status == :title
        row.each_with_index {|v, i|
          sheet_title[v] = i
        }
      else
        id = "#{row[12]}:#{row[13]}"  # prefix:name を合成する
        sheet_labels << row
        @labels[id.to_sym] = row
      end
    }
    if sheet != nil
      @sheets << {:name => sheet_name, :title => sheet_title, :labels => sheet_labels}
    end
  end

  def get_status(depth)
    if (depth == nil)
      status = :sheet
    elsif (depth == "depth")
      status = :title
    else
      status = :label
    end
    status
  end
end

#--------- 呼び出し例 -----------
if __FILE__ == $0
  taxonomyinfos = {}
  # 必要な業種データだけを読み込む。
  taxonomyinfos[:edu] = EdinetTaxonomyInfo::load(:edu)
  taxonomyinfos[:fnd] = EdinetTaxonomyInfo::load(:fnd)

  #--- fnd の情報にアクセス ---
  taxonomyinfos[:fnd].sheets.each {|s|
    puts "====================================="
    puts s[:name]
    s[:labels].each {|item|
      # depth, 標準ラベル を表示順、計算関係でインデントをつけて表示
      puts "   " * item[DEPTH_INDEX].to_i + item[1]
    }
  }

  #--- edu の情報にアクセス ---
  p taxonomyinfos[:edu].sheets[0][:name]
  p taxonomyinfos[:edu].sheets[0][:labels][0]
  p taxonomyinfos[:edu].labels["cte:NoncurrentAssets".to_sym]
  p taxonomyinfos[:edu].labels["edu:EducationalResearchInstrumentAndEquipmentEDU".to_sym]

end