# == Schema Information
# Schema version: 51
#
# Table name: fraza_typ
#
#  fraza_typ_id :integer         primary key
#  typ_opis     :text            
#  typ_symbol   :text            
#  synhead_list :text            
#  semhead_list :text            
#  jednoglowa   :boolean         
#  created_at   :timestamp       
#  updated_at   :timestamp       
#

 #
 # This file is part of the Anotatornia suite.
 # 
 # Copyright © 2007, 2008, 2009, 2010 by Instytut Podstaw Informatyki
 # Polskiej Akademii Nauk (IPI PAN; Institute of Computer Science, Polish
 # Academy of Sciences; cf. www.ipipan.waw.pl).  All rights reserved.
 # 
 # This file may be distributed and/or modified under the terms of the
 # GNU General Public License version 3 as published by the Free Software
 # Foundation and appearing in the file COPYING included in the packaging
 # of this file.  (See http://www.gnu.org/licenses/translations.html for
 # unofficial translations.)
 # 
 # A commercial license is available from IPI PAN (contact
 # Michal.Ciesiolka.waw.pl or ipi.waw.pl for more
 # information).  Licensees holding a valid commercial license from IPI
 # PAN may use this file in accordance with that license.
 # 
 # This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
 # THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 # PURPOSE.
 #

class FrazaTyp < ActiveRecord::Base

  @@downhash = nil
  
  def self.downhash
    # zwraca hasz ozn => id etykietowany oznaczeniami fraz małymi literami
    unless @@downhash
      @@downhash = Hash.new
      self.find(:all).each{|ft|
        @@downhash[ft.typ_symbol.downcase] = ft.fraza_typ_id
      }
    end
    @@downhash
  end # of self.downhash



  def self.wybor
    self.find(
              :all,
              :order => :typ_symbol).collect { |ft|
      [ ft.typ_symbol, 
        ft.fraza_typ_id]
    }
  end

    def self.typy_glow
      self.provide_typy_glow
      @@typy_glow
    end
      
    def klasy_glowy(head_symbol)
      if  /synh/ =~ head_symbol.to_s
        head_symbol = :synhead_list
      elsif /semh/ =~ head_symbol.to_s
        head_symbol = :semhead_list
      else raise "nie rozpoznany symbol głowy!"
      end
      FrazaTyp.provide_typy_glow
      kgs = self.send( head_symbol ).split(",").collect{ |ht|
        @@typy_glow[ht]  }
      # chcemy zwrócić tablicę dwóch tablic: głów typowych i głów nietypowych
      typowe = kgs[0]
      if kgs[1, kgs.size] : nietypowe =  kgs[1, kgs.size].flatten.uniq
      else       nietypowe = []
      end
      return [typowe, nietypowe]
    end # of klasy_glowy


    def dopuszcza_glowe?( head_sym, token, param)
      # jeśli klasa gram. tokenu jest na liście typowych dla głowy, zwracamy [-1, token, lemat ],
      # jeśli jest na liście nietypowych, zwracamy [0, token], 
      # jeśli nie ma na żadnej liście, zwracamy nil.
      if token 
        le = token.disambs(param)[0].leksem
        kg = le.klasa_gram.klasa_gram_ozn
        lemat_1, lemat0 = le.lemat, le.lemat + " (!)"
      else
        kg, lemat_1, lemat0 = nil, "(brak)", "(brak (!))"
      end
      kgs = self.klasy_glowy( head_sym )
      if kgs[0].include?(kg) : return [-1, token, lemat_1]
      elsif kgs[1].include?(kg) : return [0, token, lemat0]
        # takie tablice będziemy sortować, więc mamy zdef. metodę <=> egz. klasy Token.
        # dokładamy lemat, bo będziemy tworzyć listę głów, na której ma być lemat, a nie orth
      else return nil
      end
    end

    def moze_bez_glowy?( head_sym )
      # bo brak głowy w konkretnych typach fraz AP 
      # nie ma być czymś nietypowym, jeśli dopuszczalny
      # ale u Eli ma być nietypowy, jeśli na niepierwszym miejscu listy
      x = self.klasy_glowy( head_sym ).flatten.include?( nil ) 
      if DlaEli.x
        y = self.klasy_glowy( head_sym ).flatten.include?( nil ) 
        # tu było coś dziwnego i u Eli nie chciało działać, więc 2008/03/31 dodaję flatten
      else y = true
      end
      if x and y : return -1
      elsif x and not y : return 0
      else return nil
      end
    end
      
    def bezglowa? # bo konkretny typ fraz może nie mieć obu głów
      if self.moze_bez_glowy?( :synh) and self.moze_bez_glowy?( :semh)
        return true
      else return false
      end
    end
    
    
    def raczej_jednoglowa?
      self.jednoglowa? || (
                           self.klasy_glowy( :synh )[0] == 
                           self.klasy_glowy( :semh )[0])
    end


  private

  def self.provide_typy_glow
    unless defined?( @@typy_glow )
      @@typy_glow = Hash.new
      klasy_gram = KlasaGram.find(:all).collect{|kg| kg.klasa_gram_ozn }.sort
      @@typy_glow["any"]= klasy_gram
      @@typy_glow["none"] =[nil]
      klasy_gram.each{ |kg| @@typy_glow[kg] = [kg] }
      CzM.find(:all).each{ |czm|
        @@typy_glow[czm.cz_m_nazwa] = czm.klasa_gram.collect{|kg| kg.klasa_gram_ozn }.sort
      }
    end # of #{unless defined? @@typy_glow}
  end # of #{inicjuj_typy_glow}.

  @@typy = Hash.new
  # będzie to hasz #*|{ 'VP' => 8, 'AdjP' => \<…> }| tworzony dynamicznie
  def self.find_id( typ_symbol )
    unless    @@typy[ typ_symbol] 
      sfind =  self.find( :first, :conditions => {:typ_symbol => typ_symbol} )
      if sfind
        @@typy[ typ_symbol ] = sfind.fraza_typ_id
      else puts "brak symbolu :::::#{typ_symbol}::::::"
      end
    end
    return  @@typy[ typ_symbol ]
  end # of #{self.find_id}



end # of class


### Local Variables: 
### mode: ruby
### End:
