package main;

use Vector2;
use Carp;

sub deep_copy {
    my ($x) = @_;
    my ($type) = ref $x;
    if (not $type) {
	return $x;
    } elsif ($type eq "ARRAY") {
	if (grep { /[^\d\.e+-]/i } @$x) {
	    return [ map { deep_copy($_) } @$x ];
	} else {
	    return Vector2->new(@$x);
	}
    } elsif ($type eq "HASH") {
	return { map { $_=>deep_copy($x->{$_}) } keys %$x };
    } elsif (grep { $type eq $_ } qw(CODE) ){
	# shallow copy
	return $x;
    } elsif (grep { $type eq $_ } qw(SCALAR REF GLOB LVALUE) ){
	carp "don't know how to deep copy a $type. shallow copying\n";
	return $x;
    } else {
	# Objects (blessed references): do shallow copy
	# Also, Vector's are processed by this case, but it has a clone
	# operator "=" which in fact performs deep copying.
	return $x;
    }
}

sub po2 {
    my ($n) = @_;
    my ($r) = 1;
    while ($n > 0) { $r += $r; --$n; }
    while ($n < 0) { $r /= 2; ++$n; }
    return $r;
}

sub parent_class {
    my ($CLASS) = @_;
    my (@PAR) = eval "@" . $CLASS . "::ISA";
    die "sorry, can't deal with multiple inheritance: \@${CLASS}::ISA=(@PAR)"
	if $#PAR > 0;
    return $PAR[0];
}

sub print_hash {
    my ($h) = @_;
    my ($k);
    print "{";
    foreach $k (keys %$h) {
	print " $k:$h->{$k}";
    }
    print " }\n";
}

### these are used in Heap and BST

sub rc2xy {
    my ($host, $VC, $r, $c) = @_;
    # $VC is the class name of vertices in $host
    my ($lv, $x, $size, $t);
    $lv = $host->cget(-dispheight);
    $x = ($c+0.5) * po2($lv-$r+1);
    $x = Vector2->new( $x+0.5, $r+0.5 );
#    $x->[1] += ($c % 2) ? -0.2 : 0.2 if ($r >= $lv);
    $t = $host->cget(-node_opts);
    $size = ( ref $t and $t->{-size} ) ? $t->{-size} : Configurable::cget($VC, -size);
    return $x->pw_mul($size)->pw_mul($host->cget(-skip) + 1);
}

1;

