# -*- encoding: UTF-8 -*-
# enfeditor version: 1.0.0.0
require 'enfeditor'
require 'logger'
include EnfEditor

class ApplyDaimlerSetting

  def initialize
    @logger = Logger.new( STDOUT )
  end

  def exec_with_log( message, &block )
    @logger.info "#{message} Start..."
    yield
    @logger.info "#{message} done"
  end

  def replace_invalid_character( name )
    new_name = nil
    # valid characters
    valid_chr = /[^a-zA-Z0-9\.\+_\-\(\)@]/
    new_name = name.gsub( valid_chr, '_' )

    return new_name
  end  

  def add_properties( session )
    session.model.components.each do |compo|
      unless compo.name.nil? || compo.name.empty?
        compo.name = replace_invalid_character( compo.name )
      end

      # add system properties
      unless compo.name.nil? || compo.name.empty?
        if compo.component_type == "PART"
          post_fix = "_prt"
        else
          post_fix = "_asm"
        end
        compo.overwrite_user_property( 'PartNumber', compo.name + post_fix, :text )
      end
      unless compo.name.nil? || compo.name.empty?
        compo.overwrite_user_property( 'Nomenclature', compo.name, :text )
      end
      unless compo.part_revision.nil? || compo.part_revision.empty?
        compo.overwrite_user_property( 'Revision', compo.part_revision, :text )
      end      
    end
  end

  def adjust_layer_filters( session )    
    # Remove all layer filters
    session.model.layer_filters.each do |lf|
      lf.delete!
    end
    # Create default layer filter
    dlf = session.model.create_layer_filter("Show_Only", true)
    dlf.set_layer_number_visibility(0, true)
    session.model.components.each do |compo|
      next if compo.assembly?      
      # Force following elements to be hidden:
      #   Sheet(Volume), IsoEdge, IsoVertex, Axis, IsoSurface
      elem_array_hidden = []
      elem_array_hidden += compo.volumes.select {|vol| vol.open_close_flag == :open}
      elem_array_hidden += compo.isolated_edges
      elem_array_hidden += compo.isolated_vertices  
      elem_array_hidden += compo.axes    
      compo.comprep_list.each do |comprep|
        next if comprep.comprep_type != 'brep'        
        elem_array_hidden += comprep.child_element_list.tsurfaces.map{|tsur| tsur.surface if tsur.faces.empty?}.compact
        break
      end      
      elem_array_hidden.each{|elem| elem.display = false}      
      # Reset layer numbers for following elements: 
      #   Volume, IsoEdge, IsoVertex, Axis, IsoSurface, Annotation
      elem_array = []
      elem_array += compo.volumes.select {|vol| vol.open_close_flag == :close}      
      elem_array += elem_array_hidden
      elem_array.each do |elem|
        if elem.display?
          elem.layer = 0
        else
          elem.layer = 1
        end
      end
      # Just reset for annotations as their visibility is controlled by views
      compo.annotations.each do |anno|
        anno.layer_number = 1
      end
    end
  end

  def validate_face_transparency( session )
    session.model.faces.each do |face|
      if face.has_material_color?
        color = face.material_color
        if color.color_type == :alpha
          if color.alpha[0] - 0.2 < 0.0
            face.material_color = EEMaterialColor.new(:alpha, [0.2])
          end
        elsif color.color_type == :rgba
          if color.rgba[3] - 0.2 < 0.0
            face.material_color = EEMaterialColor.new(:rgba, [color.rgba[0],color.rgba[1],color.rgba[2],0.2])
          end
        else
          @logger.warn "Alpha is not set"
        end
      else
        @logger.warn "Color is not set"
      end
    end
  end


  def execute( argv )
    EnfEditor::EESession.open( argv ) do |session|
      input = session.parameter['inputfile']
      outputfile = session.parameter['outputfile']      
      exec_with_log( "Reading enf:" + input ) do
        session.read_enf( input )
      end      

      exec_with_log( "Validating face transparency" ) do
        validate_face_transparency( session )
      end

      exec_with_log( "Adding properties" ) do
        add_properties( session )
      end

      exec_with_log( "Adjusting layer filters" ) do
        adjust_layer_filters( session )
      end

      exec_with_log( "Writing enf:" + outputfile ) do
        session.write_enf( outputfile )
      end
    end
  rescue Exception => ex
    @logger.error "Failed."
    @logger.error ex
    raise ex
  else
    @logger.info "Complete."
  end
end

if $0 == __FILE__
  # main program
  exec = ApplyDaimlerSetting.new
  exec.execute( ARGV )
end