# == Schema Information
# Schema version: 51
#
# Table name: statusy
#
#  statusy_id                :integer         primary key
#  akapit_transzy_id         :integer         not null
#  akapit_id                 :integer         not null
#  segmentation              :integer         default(-1)
#  sentences                 :integer         default(-1)
#  morphosyntactic           :integer         default(-1)
#  word_senses               :integer         default(-1)
#  syntactic_words           :integer         default(-1)
#  named_entities            :integer         default(-1)
#  syntactic                 :integer         default(-1)
#  segmentation_uzid         :integer         
#  sentences_uzid            :integer         
#  morphosyntactic_uzid      :integer         
#  word_senses_uzid          :integer         
#  syntactic_words_uzid      :integer         
#  named_entities_uzid       :integer         
#  syntactic_uzid            :integer         
#  segmentation_odrzucony    :boolean         
#  sentences_odrzucony       :boolean         
#  morphosyntactic_odrzucony :boolean         
#  word_senses_odrzucony     :boolean         
#  syntactic_words_odrzucony :boolean         
#  named_entities_odrzucony  :boolean         
#  syntactic_odrzucony       :boolean         
#  created_at                :timestamp       
#  updated_at                :timestamp       
#  transza_id                :integer         
#

 #
 # 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 Statusy < ActiveRecord::Base

  belongs_to :akapit_transzy
  belongs_to :akapit # używane m.in. przez 015_odżółć.rb
  belongs_to :transza


  STATI = AkapitTranszy::STATI
  DZIAŁAJĄCE = PoziomyAnotacji::DZIAŁAJĄCE

  
  def set_poziom( poziom, wartosc, bez_uS=nil )
    logger.info "@@@@ (statusy id #{self.id}).set_poziom: poziom #{poziom.inspect}, wartosc #{wartosc.inspect}, bez_uS #{bez_uS.inspect}"
    if wartosc.kind_of?( Symbol )
      wert = STATI[ wartosc ]
    else wert = wartosc
    end
    self.send( "#{poziom}=", wert )
    self.save!
    self.propaguj_dopuszczalność( poziom )    #  ta metoda mnie zapisze. 
    self.akapit_transzy.update_Status unless bez_uS
  end # of #{set_poziom}


  def propaguj_dopuszczalność( poziom )
    if self.reload.send( poziom ) >= STATI[ :zweryfikowany ]
      PoziomyAnotacji.nastepniki( poziom ).each { |poz197|
        if self.send( poz197 ) == STATI[ :nie_dopuszczony ]
          self.set_poziom( poz197, STATI[ :dopuszczony ] )
        end
      }
    else
      PoziomyAnotacji.wyzsze( poziom ).each { |poz197|
        self.set_poziom( poz197, STATI[ :nie_dopuszczony ] )
      }
    end
    self.save!
  end # of #{propaguj_dopuszczalność}
  
  
  def uzid( poziom )
    self.send( (poziom.to_s + '_uzid') )
  end# of #uzid


  def set_uzid( poziom, uzid )
    self.send( (poziom.to_s + '_uzid='), uzid )
  end# of #set_uzid


  def statuski
    PoziomyAnotacji.poziomy_x.collect{ |poz|
      self.send( poz ) }
  end # of #statuski


  def self.odżółć( poziomy = DZIAŁAJĄCE )
        [poziomy].flatten. # jak widzicie, można też podać tylko jeden poziom
      each { |poz|
      self.find( :all, :conditions => " #{poz}=#{STATI[:zweryfikowany]} and " +
                 "statusy_id = (select min( statusy_id ) from statusy sx where sx.akapit_id = statusy.akapit_id) " ).
      each { |st|
        st.akapit.token_sup.each {|tsu|
          tsu.odżółć( poz )
          puts tsu.id
        }
      }
    }
  end # of #{self.odżółć}


  private


  def self.autozatwierdź_segmentation ## ( akapit_od, akapit_do ) 
    # użyta niejawnie w~wierszu \ref{statusy:101}
    if self.find_by_sql( [" select count(*) as ile 
from 
statusy s inner join akapit_transzy akat using( akapit_transzy_id, akapit_id )
where
      akapit_id in (select distinct akapit_id from token  where sg_choice_id is null)
and
      s.segmentation < ?
", 
                          STATI[:zweryfikowany]] 
                         )[ 0 ].ile.to_i != 0
      return Akapit.autozatwierdź_segmentation ## ( akapit_od, akapit_do )
    end
  end # of #{self.autozatwierdź_segmentation}.


  def self.dopuść_minimalne ##( akapit_od, akapit_do )
    PoziomyAnotacji.minimalne.each{ |poz|
      if self.find( :first, :conditions => { poz => -1})
        self.connection.execute " update statusy set #{poz}=0 where #{poz}=-1" ## +
        ## " and akapit_id between #{akapit_od} and #{akapit_do}"
      end
      self.send( "autozatwierdź_#{poz}" ) ##, akapit_od, akapit_do
      # \label{statusy:101}
    }
    true
  end # of #{self.dopuść_minimalne}


  
  def self.uzupełnij_tabelę ## ( akapit_od, akapit_do )
    idæ_nullæ = " select akapit_transzy_id, at.akapit_id, at.transza_id from akapit_transzy at left outer join statusy " + 
      " using( akapit_transzy_id )" +
      " where statusy_id is null "
    if self.find_by_sql " select 1 where exists (#{idæ_nullæ})"
      raise "Table akapit_transzy is empty!"  unless AkapitTranszy.find( :first )
      self.connection.execute( "insert into statusy( created_at, akapit_transzy_id, akapit_id, transza_id ) " + 
                               idæ_nullæ.sub( "select", "select current_timestamp, " ) )
      self.dopuść_minimalne ## ( akapit_od, akapit_do )
      true
    else
      nil
    end #of main #{unless},
  end # of #{self.uzupełnij_tabelę}.
  
  
  def self.uzupełnij_transza_id
    ret204=false
    if ct203 = self.count( :conditions => "transza_id is null" ) != 0
      puts "#{ct203} statusów beztranszowych — utranszawiam"
      self.connection.execute " update statusy set transza_id=(" +
        "select transza_id from akapit_transzy at " +
        " where at.akapit_transzy_id=statusy.akapit_transzy_id) where " +
        "transza_id is null"
      return true
    else
      return false
    end
      
  end # of #{self.uzupełnij_transza_id}


  ##  Transza.zrob_transze # żeby zainicjować tę klasę, co spowoduje ewentualne dotworzenie akapitów transzy.
  ##  uzupełnij_tabelę 
  # wykonałoby w~szczególności #  {self.dopuść_minimalne}, które z kolei zatwierdzą segmentacje, które można automatycznie.


  def self.dopuść_word_senses
    if DZIAŁAJĄCE.include?( :word_senses )
      coś_zrobiłam185 = false
      self.find( :all, :conditions => [ "morphosyntactic>=? and word_senses<?", 
                                        STATI[:zweryfikowany],
                                        STATI[:dopuszczony]] ).each { |stat185|
        stat185.propaguj_dopuszczalność( :morphosyntactic )
        coś_zrobiłam185 = true unless coś_zrobiłam185
      }
      coś_zrobiłam185
    end
  end # of #{self.dopuść_word_senses}

  dopuść_word_senses


  def self.autozatwierdź_word_senses
    dopuść_word_senses # #propaguj_dopuszczalność zawiera utozatwierdzenie \ac{WSD}, więc poniższe jest obsoletne i~powinno zwrócić #{false}.
    # piszemy czysty żywy \ac{SQL}, bo \ac{WSD} są poziomem maksymalnym i~nie ma co wobec tego propagować dopuszczalności.
    max188 = Statusy.maximum( :updated_at )
    puts Time.now.to_s( :db )
    puts "max188= " + max188.to_s( :db )

    self.connection.execute(  "update statusy set word_senses=16, " +
                              " word_senses_uzid=#{Uzytkownik.natror.id}, " +
                              " updated_at=current_timestamp where " +
                              " word_senses=0 and " + # czyli jesteśmy ms-zweryf.
                              " ( (not exists (select interpretacja_id from interpretacja i " +
                              " inner join token tok using( token_id ) " +
                              " where i.cz_m_leksem_id is not null " +
                              " and  i.disamb='t' and  tok.akapit_id=statusy.akapit_id ))" +
#                              " or ( statusy.morphosyntactic>=16 and not exists " +
  #                            " ( select interpretacja_id from interpretacja i  " +
    #                          " inner join token tok using( token_id )" +
    #                          " where i.cz_m_leksem_id is not null " + 
    #                          " and i.disamb='t' and tok.akapit_id=statusy.akapit_id ) )" +
                              " )"
                              )
    # był tu błędny człon koniunkcji #{where i.disamb='t'}     — gdy nie ma zawężenia statusu ms do zweryfikowanych. To spowodowało błędne oznaczenie 141 tokenów w~57 akapitach.
    # teraz dla danego akapitu ma albo nie być wcale żadnego ms-tagu sensownego, albo, jeśli akapit jest ms-zweryf., wystarczy, że nie ma sensownej dyzambiguacji.
    
    puts Time.now.to_s( :db )
    if max188 < Statusy.maximum( :updated_at )
      AkapitTranszy.find_by_sql( [ "select akapit_transzy.* from akapit_transzy inner join statusy s using( akapit_transzy_id ) where s.updated_at>=?", max188] ).
        each { |akat193|
        akat193.update_Status
        puts akat193.id
      }
      return true
    else return false
    end
  end # of #{self.autozatwierdź_word_senses}

  
  def autozatwierdź_word_senses
if self.reload.morphosyntactic >= STATI[ :zweryfikowany ]
      ## robimy dla #:word_senses
      if self.class.find_by_sql(
                                      # 2009/10/22 kolejna próba ustawienia testu: poprzednia dała 600 akapitów błędnie zatwierdzonych.
                                      # 2009/10/26 kolejna próba dała 326 akapitów błędnie zatwierdzonych jako pustospełnione.
                                      "select count(*) as ile from interpretacja i inner join token tok using( token_id ) where i.cz_m_leksem_id is not null and  i.disamb='t' and  tok.akapit_id=#{self.akapit_id}  "
                                )[0].ile.to_i == 0
        ##              not self.akapit.reload.primus_sensibilis
        # to wydaje się nie działać i prowadzić do totalnej katastrofy.
        logger.info  "@@@@@ ak. #{self.akapit_id} " +
          "akat #{self.akapit_transzy_id} wsd zatw. autom. (pustospełnione)."
        self.reload.set_poziom( :word_senses, STATI[ :zweryfikowany ] )
        self.word_senses_uzid = Uzytkownik.natror.id
        self.save!
      else
        logger.info  "@@@@@ ak. #{self.akapit_id} akat #{self.akapit_transzy_id} ma sensy."
      end
    end # of if morphosyntactic

  end # of instance #{autozatwierdź_word_senses}


end

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