# coding: utf-8 (äüöß€)   vim: ts=2 sw=2 fdm=marker
#
# Free ENDA Ruby Standard Library XUBetrieb stnd.rb
#
# (c) 2010, 2011, 2012 Matthias Lüttgert, ENDA GmbH & Co. KG
#
# This library is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3 of the License, or (at your option) any later
# version.
#
# This library is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, see <http://www.gnu.org/licenses/>.
#
# DEUTSCH:
#
# Diese Bibliothek ist freie Software. Sie können sie unter den Bedingungen der GNU
# General Public License, wie von der Free Software Foundation veröffentlicht,
# weitergeben und/oder modifizieren, entweder gemäß Version 3 der Lizenz oder
# (nach Ihrer Option) jeder späteren Version.
#
# Die Veröffentlichung dieser Bibliothek erfolgt in der Hoffnung, daß es Ihnen von
# Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite
# Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN
# ZWECK. Details finden Sie in der GNU General Public License.
#
# Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem
# Programm erhalten haben. Falls nicht, siehe <http://www.gnu.org/licenses/>.
#
# == Zweck ==
#
# Diese Bibliothek stellt Funktionen zur Ausgabe des Zeitstemples sowie
# numerischer Repräsentationen einzelner Teile des Zeitstempels sowie Test- und
# Konvertierungsfunktionen für Zeit und Zahlen zur Verfügung.
#
# == Inbetriebnahme ==
#
# Sie benötigen Ruby Version 1.8.x oder 1.9.x, um diese Bibliothek nutzen zu können.
# Andere Versionen können ebenfalls funktionieren.
# Legen Sie den Bibliotheksordner neben die Anwendung, die diese Bibliothek nutzen
# soll und laden Sie diese Datei z. B. mit
#
# require '../../free_ruby_enda/lib/stnd'
#


# now1
#   Liefert eine dem ISO-Datumsformat sehr ähnliche, jedoch besser lesbare
#   Zeichenkette mit dem aktuellen Datum und der aktuellen Uhrzeit
#
def now1
  # now1 liegt auf dem global scope und kann nur per Object.now1 gerufen werden
  # und das auch nur, wenn es public gemacht wird
  return Time.now.strftime("%Y-%m-%d %H:%M:%S")
end
public :now1


# has_content
#   Prüft den übergebenen Wert auf Existenz und Inhalt.
# 
# Rückgabewert
#   unveränderter Wert     wenn Inhalt vorhanden oder komplexer Typ
#   nil                    sonst
#
# Aufrufbeispiel
#   if value = has_content(any_input)
#     ...
#
def has_content(value)
  return nil unless value
  return nil if value.to_s.strip.length == 0
  return value
end
public :has_content


# Damit die Monthnames überschrieben werden können:
# public Date
# class Object::Date
#  MONTHNAMES = [nil] + %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember)
# end

class Stnd
  def Stnd.now
    return Time.now.strftime("%Y-%m-%d %H:%M:%S")
  end

  def Stnd.now_date_number
    return Time.now.strftime("%Y%m%d").to_i
  end

  def Stnd.now_time_number
    return Time.now.strftime("%H%M%S").to_i
  end

  def Stnd.current_date_number
    return Time.now.strftime("%Y%m%d").to_i
  end

  def Stnd.current_time_number
    return Time.now.strftime("%H%M%S").to_i
  end

  def Stnd.test_stuff
    puts "Environment:"
    ENV.each { |key, value| puts "#{key} => #{value}" }
    puts "\nConfiguration:"
    CONFIG.each { |key, value| puts "#{key} => #{value}" }
    puts "\nOperating System is: #{CONFIG['host_os']}"
  end

  def Stnd.get_bool(text)
    return nil if text.nil?
    text = text.strip
    # J/j/Ja/JA/ja/Y/y/Yes/YES/yes/1 bzw. N/n/Nein/NEIN/nein/NO/no/No/0
    return 1 if text =~ /^[jy1a].*/ui
    return 0 if text =~ /^[n0i].*/ui
    return nil
  end

  def Stnd.numerical_date( string_date )
    return 0 if string_date.nil? || string_date.empty?
    match = /(\d{1,2})\.(\d{1,2})\.(\d{2,4})\.?/.match(string_date)
    if match
      year = match[3]
      if year.length == 2
        if year.to_i < 30
          year = '20' + year
        else
          year = '19' + year
        end
      end
      return sprintf("%04d%02d%02d", year.to_i, match[2].to_i, match[1].to_i).to_i
    end
    begin
      d = Date.parse(string_date, true)
    rescue
      return 0
    end
    return sprintf("%04d%02d%02d", d.year, d.month, d.day).to_i
  end

  def Stnd.numerical_time( string_time )
    return 0 if string_time.nil? || string_time.empty?
    match = /(\d{2})\:(\d{2})\:(\d{2}).*/.match(string_time)
    if match
      return match[1].to_i*10000 + match[2].to_i * 100 +match[3].to_i
    end
    msg = "ERROR! string_time <#{string_time}> doesn't match time expression in Stnd class"
    puts msg
    raise ParseException.new, msg
  end

  def Stnd.date_to_iso( datum )
    if datum.length == 4
      return datum.to_s + "-01-01"
    else
      if datum.length == 7
        date = datum.split('.')
        isodate = date[1] + "-" + date[0]+ "-01"
      else
        date = datum.split('.')
        isodate = date[2] + "-" + date[1] + "-" + date[0]
        return isodate
      end
    end
  end

  def Stnd.numdate_to_iso( numdat )
    datum = numdat.to_s
    return datum[0,4] + "-" + datum[4,2] + "-" + datum[6,2]
  end

  def Stnd.is_valid_date( string_date )
    return true if string_date.blank?
    number_date = numerical_date( string_date )
    return false if number_date.to_i == 0
    return true
  end

  def Stnd.is_valid_float_or_empty(string)
    return true if string.nil? || string.strip.blank?
    if string.to_f == 0.0 && string[0,1] != "0"
      return false
    end
    return true
  end

  def Stnd.is_valid_int_or_empty(string)
    return true if string.nil? || string.strip.blank?
    if string.to_i == 0 && string.strip != "0"
      return false
    end
    return true
  end

end

# Exceptions
# Exception class could have constructor to take arguments evaluated later on rescue
class ParseException < RuntimeError
end

class NotImplementedYetException < RuntimeError
end
