
# (/usr/bin/env ruby -Ku) // jruby で動作しなくなるので外す
#
# 2009-03-11 katoy  modify for EDINET 2009 taxonomy
# 2009-04-18 katoy  add getAllKindName
# 2009-04-19 katoy  add kind2names
#
# http://www.fsa.go.jp/search/20090309.html
#  の xls ファイルを シート(業種)毎 に CSV ファイルで保存した。
#
# その CSV ファイルを読込み、利用する例である。
# XBRL インスタンスファイルの情報を
#   項目名(prefix:nake) -> 日本語名称ラベルに変換
# するのに利用できる。
# また、項目の表示順序、計算関係も取得できる。

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

$KCODE="utf8"

# csv ファイルでのカラム位置 (0オリジン)
DEPTH_INDEX = 23
PREFIX_INDEX = 13
LOCALNAME_INDEX = 14

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

  # URL から業種id を得る
  def self.url2kind(url)
    @@URL2KIND[url[0..45]] # 45: @@URL2KIND の key の文字列長さ
  end

  # 業種id から業種名を得る
  def self.kind2names(kind)
    @@KIND2CSV[kind]
  end

  # 業種id を指定して、業種タクソノミデータを読み込む。
  def self.load(kind)
    load_file(@@DATA_DIR + @@KIND2CSV[kind][0])
  end
  # ファイルを指定して、業種タクソノミデータを読み込む。
  def self.load_file(file_path)
    taxonomyinfo = TaxonomyInfo.new
    taxonomyinfo.read_taxonomylinfo(file_path)
    taxonomyinfo
  end

  # {業種id => 業種名} をハッシュで得る。
  def self.get_alllkind_name
    ans = { }
    @@KIND2CSV.each do |k, v|
      ans[k] = v[1]
    end
    ans
  end

  # [業種名、業種ID] の組を配列で得る。
  def self.get_templates
    ans = { }
    @@KIND2CSV.each do |k, v|
      ans[v[1]] = k
    end
    ans
  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|
      # row.each_with_index { |r, i| puts "#{i}: #{r}"}
      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[PREFIX_INDEX]}:#{row[LOCALNAME_INDEX]}"  # 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|
    if s[:name] != nil
      puts "====================================="
      puts s[:name]
      s[:labels].each {|item|
        # depth, 標準ラベル を表示順、計算関係でインデントをつけて表示
        puts "   " * item[DEPTH_INDEX].to_i + item[1]
      }
    end
  }

  #--- 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
