#!/usr/bin/env python3
"""
Test #93: Vector arithmetic operations
"""

import mcrfpy
import sys
import math

# Setup scene
test = mcrfpy.Scene("test")
mcrfpy.current_scene = test

all_pass = True

# Test 1: Vector addition
try:
    v1 = mcrfpy.Vector(3, 4)
    v2 = mcrfpy.Vector(1, 2)
    v3 = v1 + v2

    assert v3.x == 4 and v3.y == 6, f"Addition failed: {v3.x}, {v3.y}"
    print("+ Vector addition works correctly")
except Exception as e:
    print(f"x Vector addition failed: {e}")
    all_pass = False

# Test 2: Vector subtraction
try:
    v1 = mcrfpy.Vector(5, 7)
    v2 = mcrfpy.Vector(2, 3)
    v3 = v1 - v2

    assert v3.x == 3 and v3.y == 4, f"Subtraction failed: {v3.x}, {v3.y}"
    print("+ Vector subtraction works correctly")
except Exception as e:
    print(f"x Vector subtraction failed: {e}")
    all_pass = False

# Test 3: Scalar multiplication
try:
    v1 = mcrfpy.Vector(2, 3)
    v2 = v1 * 3
    v3 = 2 * v1  # Reverse multiplication

    assert v2.x == 6 and v2.y == 9, f"Scalar multiply failed: {v2.x}, {v2.y}"
    assert v3.x == 4 and v3.y == 6, f"Reverse multiply failed: {v3.x}, {v3.y}"
    print("+ Scalar multiplication works correctly")
except Exception as e:
    print(f"x Scalar multiplication failed: {e}")
    all_pass = False

# Test 4: Scalar division
try:
    v1 = mcrfpy.Vector(10, 20)
    v2 = v1 / 5

    assert v2.x == 2 and v2.y == 4, f"Division failed: {v2.x}, {v2.y}"

    # Test division by zero
    try:
        v3 = v1 / 0
        print("x Division by zero should raise exception")
        all_pass = False
    except ZeroDivisionError:
        pass

    print("+ Scalar division works correctly")
except Exception as e:
    print(f"x Scalar division failed: {e}")
    all_pass = False

# Test 5: Negation
try:
    v1 = mcrfpy.Vector(3, -4)
    v2 = -v1

    assert v2.x == -3 and v2.y == 4, f"Negation failed: {v2.x}, {v2.y}"
    print("+ Vector negation works correctly")
except Exception as e:
    print(f"x Vector negation failed: {e}")
    all_pass = False

# Test 6: Absolute value (magnitude)
try:
    v1 = mcrfpy.Vector(3, 4)
    mag = abs(v1)

    assert abs(mag - 5.0) < 0.001, f"Absolute value failed: {mag}"
    print("+ Absolute value (magnitude) works correctly")
except Exception as e:
    print(f"x Absolute value failed: {e}")
    all_pass = False

# Test 7: Boolean check
try:
    v1 = mcrfpy.Vector(0, 0)
    v2 = mcrfpy.Vector(1, 0)

    assert not bool(v1), "Zero vector should be False"
    assert bool(v2), "Non-zero vector should be True"
    print("+ Boolean check works correctly")
except Exception as e:
    print(f"x Boolean check failed: {e}")
    all_pass = False

# Test 8: Equality comparison
try:
    v1 = mcrfpy.Vector(1.5, 2.5)
    v2 = mcrfpy.Vector(1.5, 2.5)
    v3 = mcrfpy.Vector(1.5, 2.6)

    assert v1 == v2, "Equal vectors should compare equal"
    assert v1 != v3, "Different vectors should not compare equal"
    print("+ Equality comparison works correctly")
except Exception as e:
    print(f"x Equality comparison failed: {e}")
    all_pass = False

# Test 9: magnitude() method
try:
    v1 = mcrfpy.Vector(3, 4)
    mag = v1.magnitude()

    assert abs(mag - 5.0) < 0.001, f"magnitude() failed: {mag}"
    print("+ magnitude() method works correctly")
except Exception as e:
    print(f"x magnitude() method failed: {e}")
    all_pass = False

# Test 10: magnitude_squared() method
try:
    v1 = mcrfpy.Vector(3, 4)
    mag_sq = v1.magnitude_squared()

    assert mag_sq == 25, f"magnitude_squared() failed: {mag_sq}"
    print("+ magnitude_squared() method works correctly")
except Exception as e:
    print(f"x magnitude_squared() method failed: {e}")
    all_pass = False

# Test 11: normalize() method
try:
    v1 = mcrfpy.Vector(3, 4)
    v2 = v1.normalize()

    assert abs(v2.magnitude() - 1.0) < 0.001, f"normalize() magnitude failed: {v2.magnitude()}"
    assert abs(v2.x - 0.6) < 0.001, f"normalize() x failed: {v2.x}"
    assert abs(v2.y - 0.8) < 0.001, f"normalize() y failed: {v2.y}"

    # Test zero vector normalization
    v3 = mcrfpy.Vector(0, 0)
    v4 = v3.normalize()
    assert v4.x == 0 and v4.y == 0, "Zero vector normalize should remain zero"

    print("+ normalize() method works correctly")
except Exception as e:
    print(f"x normalize() method failed: {e}")
    all_pass = False

# Test 12: dot product
try:
    v1 = mcrfpy.Vector(3, 4)
    v2 = mcrfpy.Vector(2, 1)
    dot = v1.dot(v2)

    assert dot == 10, f"dot product failed: {dot}"
    print("+ dot() method works correctly")
except Exception as e:
    print(f"x dot() method failed: {e}")
    all_pass = False

# Test 13: distance_to()
try:
    v1 = mcrfpy.Vector(1, 1)
    v2 = mcrfpy.Vector(4, 5)
    dist = v1.distance_to(v2)

    assert abs(dist - 5.0) < 0.001, f"distance_to() failed: {dist}"
    print("+ distance_to() method works correctly")
except Exception as e:
    print(f"x distance_to() method failed: {e}")
    all_pass = False

# Test 14: angle()
try:
    v1 = mcrfpy.Vector(1, 0)  # Points right
    v2 = mcrfpy.Vector(0, 1)  # Points up
    v3 = mcrfpy.Vector(-1, 0) # Points left
    v4 = mcrfpy.Vector(1, 1)  # 45 degrees

    a1 = v1.angle()
    a2 = v2.angle()
    a3 = v3.angle()
    a4 = v4.angle()

    assert abs(a1 - 0) < 0.001, f"Right angle failed: {a1}"
    assert abs(a2 - math.pi/2) < 0.001, f"Up angle failed: {a2}"
    assert abs(a3 - math.pi) < 0.001, f"Left angle failed: {a3}"
    assert abs(a4 - math.pi/4) < 0.001, f"45deg angle failed: {a4}"

    print("+ angle() method works correctly")
except Exception as e:
    print(f"x angle() method failed: {e}")
    all_pass = False

# Test 15: copy()
try:
    v1 = mcrfpy.Vector(5, 10)
    v2 = v1.copy()

    assert v2.x == 5 and v2.y == 10, f"copy() values failed: {v2.x}, {v2.y}"

    # Modify v2 and ensure v1 is unchanged
    v2.x = 20
    assert v1.x == 5, "copy() should create independent object"

    print("+ copy() method works correctly")
except Exception as e:
    print(f"x copy() method failed: {e}")
    all_pass = False

# Test 16: Operations with invalid types
try:
    v1 = mcrfpy.Vector(1, 2)

    # These should return NotImplemented
    result = v1 + "string"
    assert result is NotImplemented, "Invalid addition should return NotImplemented"

    result = v1 * [1, 2]
    assert result is NotImplemented, "Invalid multiplication should return NotImplemented"

    print("+ Type checking works correctly")
except Exception as e:
    # Expected to fail with TypeError
    if "unsupported operand type" in str(e):
        print("+ Type checking works correctly")
    else:
        print(f"x Type checking failed: {e}")
        all_pass = False

print(f"\n{'PASS' if all_pass else 'FAIL'}")
sys.exit(0 if all_pass else 1)
