#![ cfg( feature = "test-support" ) ]

use ltk::test_support::diff_overlay_ids;
use ltk::OverlayId;

fn ids( xs: &[ u32 ] ) -> Vec<OverlayId>
{
	xs.iter().copied().map( OverlayId ).collect()
}

#[ test ]
fn empty_to_empty_is_no_change()
{
	let ( added, removed ) = diff_overlay_ids( ids( &[] ), &ids( &[] ) );
	assert!( added.is_empty() );
	assert!( removed.is_empty() );
}

#[ test ]
fn first_frame_marks_everything_added()
{
	let ( added, removed ) = diff_overlay_ids( ids( &[] ), &ids( &[ 1, 2, 3 ] ) );
	assert_eq!( added,   ids( &[ 1, 2, 3 ] ) );
	assert!( removed.is_empty() );
}

#[ test ]
fn empty_next_marks_everything_removed()
{
	let ( added, removed ) = diff_overlay_ids( ids( &[ 1, 2, 3 ] ), &ids( &[] ) );
	assert!( added.is_empty() );
	let mut removed_sorted = removed;
	removed_sorted.sort();
	assert_eq!( removed_sorted, ids( &[ 1, 2, 3 ] ) );
}

#[ test ]
fn unchanged_set_produces_no_diff()
{
	let ( added, removed ) = diff_overlay_ids( ids( &[ 1, 2, 3 ] ), &ids( &[ 1, 2, 3 ] ) );
	assert!( added.is_empty(),   "no overlays should be added" );
	assert!( removed.is_empty(), "no overlays should be removed" );
}

#[ test ]
fn order_in_next_does_not_matter_for_diff()
{
	// Same set, different order — the overlay surfaces should be reused, not
	// recreated.
	let ( added, removed ) = diff_overlay_ids( ids( &[ 1, 2, 3 ] ), &ids( &[ 3, 2, 1 ] ) );
	assert!( added.is_empty() );
	assert!( removed.is_empty() );
}

#[ test ]
fn open_one_panel_marks_only_it_added()
{
	let ( added, removed ) = diff_overlay_ids( ids( &[ 1 ] ), &ids( &[ 1, 2 ] ) );
	assert_eq!( added,   ids( &[ 2 ] ) );
	assert!( removed.is_empty() );
}

#[ test ]
fn close_one_panel_marks_only_it_removed()
{
	let ( added, removed ) = diff_overlay_ids( ids( &[ 1, 2 ] ), &ids( &[ 1 ] ) );
	assert!( added.is_empty() );
	assert_eq!( removed, ids( &[ 2 ] ) );
}

#[ test ]
fn swap_one_panel_marks_one_added_one_removed()
{
	let ( added, removed ) = diff_overlay_ids( ids( &[ 1, 2 ] ), &ids( &[ 1, 3 ] ) );
	assert_eq!( added,   ids( &[ 3 ] ) );
	assert_eq!( removed, ids( &[ 2 ] ) );
}

#[ test ]
fn added_preserves_next_order()
{
	// Creation order is deterministic — the runtime instantiates new
	// surfaces in the order the app returned them, and diffing must
	// preserve it.
	let ( added, _removed ) = diff_overlay_ids( ids( &[] ), &ids( &[ 7, 3, 5 ] ) );
	assert_eq!( added, ids( &[ 7, 3, 5 ] ) );
}
