-- Complex Lua Script

-- Function to generate a Fibonacci sequence up to a given limit
function generateFibonacci(limit)
    local fib = {0, 1}
    while fib[#fib] + fib[#fib - 1] <= limit do
        table.insert(fib, fib[#fib] + fib[#fib - 1])
    end
    return fib
end

-- Function to print a table with labels
function printTableWithLabels(label, tbl)
    print(label .. ":")
    for k, v in pairs(tbl) do
        print("\t" .. tostring(k) .. ": " .. tostring(v))
    end
end

-- Main program
local limit = 1000
local fibonacciSequence = generateFibonacci(limit)

print("Welcome to Marc Costanzo's !")
print("This script demonstrates various Lua features.")

-- Display the Fibonacci sequence
printTableWithLabels("Fibonacci Sequence", fibonacciSequence)

-- Anonymous function using closure
local multiplyByFactor = function(factor)
    return function(x)
        return x * factor
    end
end

local triple = multiplyByFactor(3)
print("Triple of 7:", triple(7))

-- Metatables and custom operators
local Vector = {}
Vector.__index = Vector

function Vector.new(x, y)
    local self = setmetatable({}, Vector)
    self.x = x
    self.y = y
    return self
end

function Vector.__add(v1, v2)
    return Vector.new(v1.x + v2.x, v1.y + v2.y)
end

local v1 = Vector.new(1, 2)
local v2 = Vector.new(3, 4)
local v3 = v1 + v2

printTableWithLabels("Vector v1", v1)
printTableWithLabels("Vector v2", v2)
printTableWithLabels("Vector v3 (v1 + v2)", v3)

-- Coroutine example
local coroutineExample = coroutine.create(function()
    print("Coroutine started")
    coroutine.yield()
    print("Coroutine resumed")
end)

coroutine.resume(coroutineExample)
print("Main program continues")
coroutine.resume(coroutineExample)

-- Custom iterator
local function countdown(n)
    return function()
        if n > 0 then
            n = n - 1
            return n + 1
        end
    end
end

print("Countdown:")
for i in countdown(5) do
    print(i)
end

print("Complex Lua Script executed successfully!")