declare -A asteroids
declare __asteroids_grid_height
declare __asteroids_grid_width

get_grid_height() {
    echo $__asteroids_grid_height
}

get_grid_width() {
    echo $__asteroids_grid_width
}

read_file() {
    filename="$1"

    if [ ! -e "$filename" ]; then
        echo "Couldn't find file: $filename"
        exit 2
    fi

    exec 3<"$filename"
    unset asteroids
    declare -g -A asteroids

    __asteroids_grid_height=0
    __asteroids_grid_width=0

    while read -u 3 line; do
        __asteroids_grid_width=${#line}
        for (( a=0; a<${#line}; a++ )); do
            char=${line:$a:1}
            if [ "${char}" == "#" ]; then
                asteroids[$a,$__asteroids_grid_height]=0
            fi
        done
        __asteroids_grid_height=$((__asteroids_grid_height+1))
    done
}

get_vector() {
    local x1=$1
    local y1=$2
    local x2=$3
    local y2=$4

    x_diff=$(($x2 - $x1))
    y_diff=$(($y2 - $y1))

    echo "$x_diff,$y_diff"
}

get_asteroids_vector() {
    local a1=$1
    local a2=$2

    local x1=${a1%,*}
    local y1=${a1#*,}
    local x2=${a2%,*}
    local y2=${a2%*,}

    get_vector $x1 $y1 $x2 $y2
}

get_angle() {
    local a1=$1
    local a2=$2

    local vector=$(get_asteroids_vector $a1 $a2)
    local move_x=${vector%,*}
    local move_y=${vector#*,}

    val="$(calc -p 'round(((90 + ((180/pi()) * atan2('$move_y','$move_x'))) % 360) * 100000000) / 100000000')"
    echo "$val"
}

get_closest_asteroid() {
    local asteroids=$1

    local IFS="|"
    local min_dist=-1
    local nearest_asteroid=
    local x=0
    local y=0

    for asteroid in $asteroids; do
        vector=$(get_asteroids_vector $our_asteroid $asteroid)
        x=${vector%,*}
        y=${vector#*,}
        # use absolute numbers for length calculation!
        x=${x#-}
        y=${y#-}

        distance=$((x+y))
        if [ $distance -lt $min_dist -o $min_dist -eq -1 ]; then
            min_dist=$distance
            nearest_asteroid=$asteroid
        fi
    done

    echo $nearest_asteroid
}

remove_asteroid_from_string() {
    local asteroids=$1
    local asteroid=$2
    local new_asteroids=
    local a

    local IFS="|"
    local seperator=""

    for a in $asteroids; do
        if [ "$a" != "$asteroid" ]; then
            new_asteroids+="${seperator}$a"
        fi
        if [ "x$new_asteroids" != "x" ]; then
            seperator="|"
        fi
    done

    echo "$new_asteroids"
}

get_angles_list() {
    local -n __asteroid_angles=$1
    printf "%s\n" "${!__asteroid_angles[@]}" | sort -g
}

