
$:.push(File::dirname($0))

load("test_prologue.rb")

class DBInstance_TestClass < TestBase

  # Instance edit functions
  def test_1_InstEdit

    # this only works in editable mode
    if ! RBA::Application::instance.is_editable?
      return 
    end

    ly = RBA::Layout::new

    ci1 = ly.add_cell( "c1" )
    ci2 = ly.add_cell( "c2" )
    ci3 = ly.add_cell( "c3" )

    linfo = RBA::LayerInfo::new
    linfo.layer = 16
    linfo.datatype = 1
    lindex = ly.insert_layer( linfo )

    linfo = RBA::LayerInfo::new
    linfo.layer = 16
    linfo.datatype = 2
    ldummy = ly.insert_layer( linfo )

    c1 = ly.cell( ci1 )
    c2 = ly.cell( ci2 )
    c3 = ly.cell( ci3 )

    c1.shapes( lindex ).insert( RBA::Box::new( 10, -10, 50, 40 ) )

    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 101, -51 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )

    inst_ref = c2.insert( inst )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 101,-51" )
    assert_equal( inst_ref.bbox.to_s, "(61,-41;111,-1)" )

    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 100, -50 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )
    inst_ref.cell_inst = inst
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50" )

    inst_ref.prop_id = 4
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50 prop_id=4" )

    inst_ref = c2.replace_prop_id( inst_ref, 5 )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50 prop_id=5" )

    inst_ref = c2.replace( inst_ref, RBA::CellInstArray::new( c3.cell_index, tr ) )
    assert_equal( inst_ref.to_s, "cell_index=2 r90 100,-50 prop_id=5" )

    inst_ref = c2.replace( inst_ref, RBA::CellInstArray::new( c1.cell_index, tr ), 7 )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50 prop_id=7" )

    inst_ref = c2.transform( inst_ref, RBA::Trans::new( 3, false, 100, 200 ) )
    assert_equal( inst_ref.to_s, "cell_index=0 r0 50,100 prop_id=7" )

    inst_ref = c2.transform( inst_ref, RBA::CplxTrans::new( 0.5, 45.0, false, RBA::DPoint::new ) )
    assert_equal( inst_ref.to_s, "cell_index=0 r45 *0.5 -18,53 prop_id=7" )

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=0 r45 *0.5 -18,53 prop_id=7" ] )

    inst_ref2 = c2.insert( RBA::CellInstArray::new( c3.cell_index, tr ), 14 )

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=0 r45 *0.5 -18,53 prop_id=7",
                         "cell_index=2 r90 100,-50 prop_id=14" ] )

    assert_equal( inst_ref.is_valid?, true )
    assert_equal( c2.is_valid?(inst_ref), true )
    c2.erase( inst_ref )
    assert_equal( inst_ref.is_valid?, false )
    assert_equal( c2.is_valid?(inst_ref), false )
    inst_ref3 = c2.insert( RBA::CellInstArray::new( c3.cell_index, tr ) )

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=2 r90 100,-50",
                         "cell_index=2 r90 100,-50 prop_id=14" ] )

    c2.erase( inst_ref2 )
    c2.erase( inst_ref3 )

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ ] )

    inst_ref2 = c2.insert( RBA::CellInstArray::new( c3.cell_index, tr ), 14 )
    inst_ref = c2.insert( RBA::CellInstArray::new( c3.cell_index, tr ), 15 )

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=2 r90 100,-50 prop_id=14",  "cell_index=2 r90 100,-50 prop_id=15" ] )

    inst_ref.delete

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=2 r90 100,-50 prop_id=14" ] )

    inst_ref = c2.insert( RBA::CellInstArray::new( c3.cell_index, tr ), 15 )
    assert_equal( inst_ref.is_regular_array?, false )
    inst_ref.na = 2
    assert_equal( inst_ref.is_regular_array?, true )
    inst_ref.nb = 21
    inst_ref.a = RBA::Point::new(1, 2)
    inst_ref.b = RBA::Point::new(10, 20)
    assert_equal( inst_ref.na, 2 )
    assert_equal( inst_ref.nb, 21 )
    assert_equal( inst_ref.a.to_s, "1,2" )
    assert_equal( inst_ref.b.to_s, "10,20" )
    assert_equal( inst_ref.is_regular_array?, true )

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=2 r90 100,-50 prop_id=14", "cell_index=2 r90 100,-50 array=(1,2,10,20 2x21) prop_id=15" ] )

    inst_ref.cplx_trans = RBA::CplxTrans::new(2.5)

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=2 r90 100,-50 prop_id=14", "cell_index=2 r0 *2.5 0,0 array=(1,2,10,20 2x21) prop_id=15" ] )

    inst_ref.transform( RBA::CplxTrans::new(2.0) )

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=2 r90 100,-50 prop_id=14", "cell_index=2 r0 *5 0,0 array=(2,4,20,40 2x21) prop_id=15" ] )

    inst_ref.transform( RBA::ICplxTrans::new(0.5) )
    assert_equal( inst_ref.cplx_trans.to_s, "r0 *2.5 0,0" )

    inst_ref.trans = RBA::Trans::new(7)

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=2 r90 100,-50 prop_id=14", "cell_index=2 m135 0,0 array=(1,2,10,20 2x21) prop_id=15" ] )

    inst_ref.transform( RBA::Trans::new(3) )
    assert_equal( inst_ref.cplx_trans.to_s, "m90 *1 0,0" )

    inst_ref.nb = 3
    inst_ref2.delete

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=2 m90 0,0 array=(2,-1,20,-10 2x3) prop_id=15" ] )

    inst_ref.explode
    assert_equal( inst_ref.to_s, "cell_index=2 m90 0,0 prop_id=15" );

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=2 m90 2,-1 prop_id=15", "cell_index=2 m90 0,0 prop_id=15", "cell_index=2 m90 20,-10 prop_id=15", "cell_index=2 m90 22,-11 prop_id=15", "cell_index=2 m90 40,-20 prop_id=15", "cell_index=2 m90 42,-21 prop_id=15" ] )

  end

  # Instance edit functions
  def test_2_InstEdit

    # this only works in editable mode
    if ! RBA::Application::instance.is_editable?
      return 
    end

    ly = RBA::Layout::new

    ci1 = ly.add_cell( "c1" )
    ci2 = ly.add_cell( "c2" )
    ci3 = ly.add_cell( "c3" )

    linfo = RBA::LayerInfo::new
    linfo.layer = 16
    linfo.datatype = 1
    lindex = ly.insert_layer( linfo )

    linfo = RBA::LayerInfo::new
    linfo.layer = 16
    linfo.datatype = 2
    ldummy = ly.insert_layer( linfo )

    c1 = ly.cell( ci1 )
    c2 = ly.cell( ci2 )
    c3 = ly.cell( ci3 )

    c1.shapes( lindex ).insert( RBA::Box::new( 10, -10, 50, 40 ) )

    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 101, -51 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )

    inst_ref = c2.insert( inst )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 101,-51" )
    assert_equal( inst_ref.bbox.to_s, "(61,-41;111,-1)" )

    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 100, -50 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )
    inst_ref.cell_inst = inst
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50" )

    inst_ref.prop_id = 4
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50 prop_id=4" )

    inst_ref = c2.transform_into( inst_ref, RBA::Trans::new( 3, false, 100, 200 ) )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 250,0 prop_id=4" )

    inst_ref = c2.transform_into( inst_ref, RBA::CplxTrans::new( 0.5, 45.0, false, RBA::DPoint::new ) )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 88,88 prop_id=4" )

    inst_ref = c2.transform_into( inst_ref, RBA::ICplxTrans::new( 0.5, 45.0, false, RBA::Point::new ) )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 0,62 prop_id=4" )

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=0 r90 0,62 prop_id=4" ] )

    c2.clear 
    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 101, -51 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )
    inst_ref = c2.insert( inst )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 101,-51" )
    assert_equal( inst_ref.bbox.to_s, "(61,-41;111,-1)" )

    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 100, -50 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )
    inst_ref.cell_inst = inst
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50" )

    inst_ref.prop_id = 4
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50 prop_id=4" )

    inst_ref.transform_into( RBA::Trans::new( 3, false, 100, 200 ) )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 250,0 prop_id=4" )

    inst_ref.transform_into( RBA::CplxTrans::new( 0.5, 45.0, false, RBA::DPoint::new ) )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 88,88 prop_id=4" )

    inst_ref.transform_into( RBA::ICplxTrans::new( 0.5, 45.0, false, RBA::Point::new ) )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 0,62 prop_id=4" )

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=0 r90 0,62 prop_id=4" ] )

    c2.clear 
    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 101, -51 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )
    inst_ref = c2.insert( inst )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 101,-51" )
    assert_equal( inst_ref.bbox.to_s, "(61,-41;111,-1)" )

    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 100, -50 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )
    inst_ref.cell_inst = inst
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50" )

    inst_ref.prop_id = 4
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50 prop_id=4" )

    c2.transform_into( RBA::Trans::new( 3, false, 100, 200 ) )
    inst_ref = nil
    c2.each_inst { |i| inst_ref = i }
    assert_equal( inst_ref.to_s, "cell_index=0 r90 250,0 prop_id=4" )

    c2.transform_into( RBA::ICplxTrans::new( 0.5, 45.0, false, RBA::Point::new ) )
    inst_ref = nil
    c2.each_inst { |i| inst_ref = i }
    assert_equal( inst_ref.to_s, "cell_index=0 r90 88,88 prop_id=4" )

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=0 r90 88,88 prop_id=4" ] )

    c2.clear 
    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 101, -51 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )
    inst_ref = c2.insert( inst )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 101,-51" )
    assert_equal( inst_ref.bbox.to_s, "(61,-41;111,-1)" )

    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 100, -50 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )
    inst_ref.cell_inst = inst
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50" )

    inst_ref.prop_id = 4
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50 prop_id=4" )

    c2.transform_into( RBA::Trans::new( 3, false, 100, 200 ) )
    inst_ref = nil
    c2.each_inst { |i| inst_ref = i }
    assert_equal( inst_ref.to_s, "cell_index=0 r90 250,0 prop_id=4" )

    c2.transform_into( RBA::ICplxTrans::new( 0.5, 45.0, false, RBA::Point::new ) )
    inst_ref = nil
    c2.each_inst { |i| inst_ref = i }
    assert_equal( inst_ref.to_s, "cell_index=0 r90 88,88 prop_id=4" )

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=0 r90 88,88 prop_id=4" ] )

    c2.clear 
    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 101, -51 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )
    inst_ref = c2.insert( inst )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 101,-51" )
    assert_equal( inst_ref.bbox.to_s, "(61,-41;111,-1)" )

    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 100, -50 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )
    inst_ref.cell_inst = inst
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50" )

    inst_ref.prop_id = 4
    assert_equal( inst_ref.to_s, "cell_index=0 r90 100,-50 prop_id=4" )

    c2.layout.transform( RBA::Trans::new( 3, false, 100, 200 ) )
    inst_ref = nil
    c2.each_inst { |i| inst_ref = i }
    assert_equal( inst_ref.to_s, "cell_index=0 r90 250,0 prop_id=4" )

    c2.layout.transform( RBA::ICplxTrans::new( 0.5, 45.0, false, RBA::Point::new ) )
    inst_ref = nil
    c2.each_inst { |i| inst_ref = i }
    assert_equal( inst_ref.to_s, "cell_index=0 r90 88,88 prop_id=4" )

    arr = []
    c2.each_inst { |i| arr.push( i.to_s ) }
    assert_equal( arr, [ "cell_index=0 r90 88,88 prop_id=4" ] )

  end

  # Instance functions
  def test_2_InstCreate

    ly = RBA::Layout::new

    ci1 = ly.add_cell( "c1" )
    ci2 = ly.add_cell( "c2" )
    ci3 = ly.add_cell( "c3" )

    linfo = RBA::LayerInfo::new
    linfo.layer = 16
    linfo.datatype = 1
    lindex = ly.insert_layer( linfo )

    linfo = RBA::LayerInfo::new
    linfo.layer = 16
    linfo.datatype = 2
    ldummy = ly.insert_layer( linfo )

    c1 = ly.cell( ci1 )
    c2 = ly.cell( ci2 )
    c3 = ly.cell( ci3 )

    c1.shapes( lindex ).insert( RBA::Box::new( 10, -10, 50, 40 ) )

    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 101, -51 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )

    inst_ref = c2.insert( inst )
    assert_equal( inst_ref.to_s, "cell_index=0 r90 101,-51" )
    assert_equal( inst_ref.bbox.to_s, "(61,-41;111,-1)" )

    assert_equal( inst_ref.is_valid?, true )

  end

  # Instance flattening
  def test_2_InstFlatten

    # this only works in editable mode
    if ! RBA::Application::instance.is_editable?
      return 
    end

    ly = RBA::Layout::new

    ci1 = ly.add_cell( "c1" )
    ci2 = ly.add_cell( "c2" )
    ci3 = ly.add_cell( "c3" )

    linfo = RBA::LayerInfo::new
    linfo.layer = 16
    linfo.datatype = 1
    lindex = ly.insert_layer( linfo )

    linfo = RBA::LayerInfo::new
    linfo.layer = 16
    linfo.datatype = 2
    ldummy = ly.insert_layer( linfo )

    c1 = ly.cell( ci1 )
    c2 = ly.cell( ci2 )
    c3 = ly.cell( ci3 )

    c1.shapes( lindex ).insert( RBA::Box::new( 10, -10, 50, 40 ) )

    tr = RBA::Trans::new( RBA::Trans::r90, RBA::Point::new( 101, -51 ) ) 
    inst = RBA::CellInstArray::new( c1.cell_index, tr )

    inst_ref = c2.insert( inst )
    assert_equal( inst_ref.is_valid?, true )
    inst_ref.flatten
    assert_equal( inst_ref.is_valid?, false )

    shapes = []
    c2.shapes( lindex ).each { |s| shapes << s.to_s }
    insts = []
    c2.each_inst { |i| insts << i.to_s }

    assert_equal( shapes.join( ":" ), "box (61,-41;111,-1)" )
    assert_equal( insts.join( ":" ), "" )

    c1.shapes( lindex ).insert( RBA::Box::new( 10, -10, 50, 40 ) )
    c2.shapes( lindex ).clear

    inst = RBA::CellInstArray::new( c1.cell_index, tr )
    inst_ref = c2.insert( inst )

    inst = RBA::CellInstArray::new( c2.cell_index, tr )
    inst_ref = c3.insert( inst )

    inst_ref.flatten( 1 )

    shapes = []
    c3.shapes( lindex ).each { |s| shapes << s.to_s }
    insts = []
    c3.each_inst { |i| insts << i.to_s }

    assert_equal( shapes.join( ":" ), "" )
    assert_equal( insts.join( ":" ), "cell_index=0 r180 152,50" )

  end

end

load("test_epilogue.rb")
