------------------------------------------------------------------------------
-- This is a script file for U61 by U-Foot (www.ufoot.org ufoot@ufoot.org)  --
-- It is free software, protected by the GPL (www.fsf.org)                  --
--                                                                          --
-- Do not hesitate to modify this file to change the behavior of U61,       --
-- that's exactly what it's done for!                                       --
------------------------------------------------------------------------------



-- this function is used to check if the script is really an U61 script ------

function user_get_program()
    return "u61"
end

-- this function returns the U61 version to be used with this script ---------

function user_get_version()
    return "1.1.0"
end


------------------------------------------------------------------------------
--                                                                          --
-- U U    6   1            U U   FFF  O   O  TTT                            --
-- U U   6   11   b        U U   F   O O O O  T                             --
-- U U - 66   1   bb  y y  U U - FF  O O O O  T                             --
-- U U   6 6  1   b b  y   U U   F   O O O O  T                             --
--  U     6   1   bb   y    U    F    O   O   T                             --
--                                                                          --
-- U61 is another block based game                                          --
-- Copyright (C) 2000-2003 Christian Mauduit (ufoot@ufoot.org)              --
--                                                                          --
-- This program is free software; you can redistribute it and/or            --
-- modify it under the terms of the GNU General Public License              --
-- as published by the Free Software Foundation; either version 2           --
-- of the License, or (at your option) any later version.                   --
--                                                                          --
-- This program is distributed in the hope that it will be useful,          --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of           --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            --
-- GNU General Public License for more details.                             --
--                                                                          --
-- You should have received a copy of the GNU General Public License        --
-- along with this program; if not, write to the Free Software              --
-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA--
--                                                                          --
-- This project is also available on Savannah (http://savannah.gnu.org)     --
------------------------------------------------------------------------------

-- couple game, you have blocks with two squares of different colors, it's
-- possible to translate and rotate them, and one need to have 4 adjacent
-- squares (at least) of the same color to make them disappear 


-- initialization ------------------------------------------------------------

function user_start()
    u61_set_height(20)
    u61_set_width(6)
end


-- shape definition ----------------------------------------------------------

function user_new_shape(num)
    return num
end 

function user_do_shape(num)
    colored_vertical_bar(2,6,num)
end


-- actions -------------------------------------------------------------------

function user_rotate_left()
    rotation_left()    
end

function user_rotate_right()
    rotation_right()    
end

function user_move_left()
    translation_x(-1)
end

function user_move_right()
    translation_x(1)
end

function user_move_down()
    translation_y(1)
end

function user_use_antidote()
    u61_cancel_curse(u61_get_oldest_curse(0))
end

-- pattern match -------------------------------------------------------------

function user_match_pattern(match_count)
    return connected_match_pattern(match_count,4)
end

function user_land()
    split_block()
end

function user_square_blown_up(x,y)
    utils_shift_column_down(x,y)
end

-- curse functions  ----------------------------------------------------------

function user_new_curse(num)
    num=mod(num,4)

    return num
end

function user_do_curse(num,sent)

end

function user_get_curse_name(num)
    name="todo..."

    return name
end

-- callback functions --------------------------------------------------------

function user_time_callback_1()
    u61_add_score(1)
end

function user_time_callback_10()

end

function user_time_callback_100()

end


-- various functions used for pattern matching -------------------------------

function utils_shift_column_down(x_col,y_bottom)
    local y
    local color

    y=y_bottom
    while y>=1 do
        color=u61_get_square_color(x_col,y-1)
        u61_set_square_color(x_col,y,color)
        y=y-1
    end
    u61_set_square_color(x_col,0,-1)

    if u61_get_curse_x()==x_col and u61_get_curse_y()<y_bottom then
        u61_set_curse_y(u61_get_curse_y()+1)
    end
end


-- Functions used in many curse scripts --------------------------------------

function utils_shift_map_up()
    local x
    local y
    local width
    local height
    local color

    width=u61_get_width()
    height=u61_get_height() 
    y=0
    while y<height-1 do
        x=0
        while x<width do
            color=u61_get_square_color(x,y+1)
            u61_set_square_color(x,y,color)
            x=x+1
        end
        y=y+1
    end

    u61_set_curse_y(u61_get_curse_y()-1)
end

function utils_clear_map()
    local x
    local y
    local width
    local height

    width=u61_get_width()
    height=u61_get_height() 
    y=0
    while y<height do
        x=0
        while x<width do
            u61_set_square_color(x,y,-1)
            x=x+1
        end
        y=y+1
    end
end

function utils_switch_lines(y1,y2)
    local x
    local color

    x=u61_get_width()-1
    while x>=0 do
        color=u61_get_square_color(x,y1)
        u61_set_square_color(x,y1,u61_get_square_color(x,y2))
        u61_set_square_color(x,y2,color)
        x=x-1
    end
end

function utils_get_highest_square_y()
    local x
    local y
    local width
    local height
    local min_y	

    width=u61_get_width()
    height=u61_get_height()
    min_y=height 
    y=0
    while y<height do
        x=0
        while x<width do
            if u61_get_square_color(x,y)>=0 then
                min_y=y
                x=width
                y=height
            end
            x=x+1
        end
        y=y+1
    end 

    return min_y   
end

function utils_get_exploding_squares()
    local x
    local y
    local n

    n=0

    x=u61_get_width()-1
    while x>=0 do 
        y=u61_get_height()-1
        while y>=0 do
            if u61_is_square_exploding(x,y)~=0 then
                n=n+1
            end
            y=y-1 
        end
        x=x-1
    end

    return n
end
-- vertical colored bar of any size ------------------------------------------

function colored_vertical_bar(y_size,nb_colors,num)
    local y

    y=0
    while y<y_size do
        u61_add_item(0,y,mod(num,nb_colors))
        num=floor(num/7)
        y=y+1
    end
end



-- defines translations ------------------------------------------------------

function translation_x(x)
    u61_set_block_x(u61_get_block_x()+x)
end

function translation_y(y)
    u61_set_block_y(u61_get_block_y()+y)
end

function translation_x_check(x)
    local i
    local dx
	
    if x>0 then
        dx=1
    else
        x=-x
        dx=-1
    end

    i=x
    while i>0 do
        translation_x(dx)
        if u61_is_block_ok()==0 then
            translation_x(-dx)
            i=0
        end
        i=i-1	          
    end
end

function translation_y_check(y)
    local i
    local dy
	
    if y>0 then
        dy=1
    else
        y=-y
        dy=-1
    end

    i=y
    while i>0 do
        translation_y(dy)
        if u61_is_block_ok()==0 then
            translation_y(-dy)
            i=0
        end
        i=i-1		          
    end
end


-- defines geometrical rotations ---------------------------------------------

function rotation_left()
    local x
    local y
    local i 

    i = u61_get_nb_items()-1
    while i>=0 do
        x = u61_get_item_x(i) 
        y = u61_get_item_y(i) 
        x,y = y,-x
        u61_set_item_x(i,x)
        u61_set_item_y(i,y)
        i = i-1
    end
end

function rotation_right()
    local x
    local y
    local i 

    i = u61_get_nb_items()-1
    while i>=0 do
        x = u61_get_item_x(i) 
        y = u61_get_item_y(i) 
        x,y = -y,x
        u61_set_item_x(i,x)
        u61_set_item_y(i,y)
        i = i-1
    end
end

-- splits the block so that every square is as low as possible ---------------

function split_get_highest_square(x)
    local y
    local height
    local y_min
    local found

    height=u61_get_height()
    y_min=height
    found=0

    y=0
    while y<height and found==0 do
        if u61_get_square_color(x,y)>=0 then
            found=1
            y_min=y
        end
        y=y+1
    end

    return y_min
end

function split_block()
    local x
    local y
    local y_min
    local size
    local i
    local width
    local height

    width=u61_get_width()
    size=u61_get_nb_items()
    x=0
    while x<width do
        y_min=split_get_highest_square(x)
        y=y_min-1
        while y>=0 do
            i=0
            while (i<size) do
                if (u61_get_block_x()+u61_get_item_x(i)==x
                    and u61_get_block_y()+u61_get_item_y(i)==y) then
                    u61_set_item_y(i,y_min-u61_get_block_y()-1)
                    y_min=y_min-1
                end
                i=i+1
            end
            y=y-1
        end 
        x=x+1
    end
end



-- connected pattern: any connected sequence of the same color is removed ---

function connected_process_item(x_test,y_test,x_list,y_list,color)
    local i
    local ok

     if u61_get_square_color(x_test,y_test)==color then
        ok=1
        i=getn(x_list)
        while i>=1 and ok~=0 do
            if x_test==x_list[i] and y_test==y_list[i] then
                ok=0
            end
            i=i-1
        end
    else
        ok=0
    end

    return ok
end

function connected_search(x,y,min_size)
    local x_list
    local y_list
    local size
    local color
    local i
    local x_test
    local y_test
    local done

    color=u61_get_square_color(x,y)
    if color>=0 then
        x_list={}
        y_list={}
        x_list[1]=x
        y_list[1]=y
        size=1
        done=0
        while done==0 do
            done=1
            i=size
            while i>=1 do
                x_test=x_list[i]+1
                y_test=y_list[i]
                if connected_process_item(x_test,y_test,x_list,y_list,color)~=0 then
                    size=size+1
                    x_list[size]=x_test
                    y_list[size]=y_test
                    done=0
                end
        
                x_test=x_list[i]
                y_test=y_list[i]+1
                if connected_process_item(x_test,y_test,x_list,y_list,color)~=0 then
                    size=size+1
                    x_list[size]=x_test
                    y_list[size]=y_test
                    done=0
                end
        
                x_test=x_list[i]-1
                y_test=y_list[i]
                if connected_process_item(x_test,y_test,x_list,y_list,color)~=0 then
                    size=size+1
                    x_list[size]=x_test
                    y_list[size]=y_test
                    done=0
                end
        
                x_test=x_list[i]
                y_test=y_list[i]-1
                if connected_process_item(x_test,y_test,x_list,y_list,color)~=0 then
                    size=size+1
                    x_list[size]=x_test
                    y_list[size]=y_test
                    done=0
                end
                
                i=i-1
            end
        end
    else
        size=0
    end

    if size>=min_size then
        i=size
        while i>=1 do
            u61_blow_up_square(x_list[i],y_list[i])
            i=i-1
        end
    end

    return size
end

function connected_match_pattern(match_count,min_size)
    local x
    local y
    local found
    local size
    local found_size

    size=0
    found=0
    found_size=0
    y=u61_get_height()-1
    while y>=0 and found==0 do
        x=u61_get_width()-1
        while x>=0 and found==0 do
            size=connected_search(x,y,min_size)
            if size>=min_size then
                found_size=size
                found=1
            end
            x=x-1
        end
        y=y-1
    end

    if found_size>=min_size then
        u61_add_score((match_count+1)*10
            *(found_size-min_size+3)
            *(found_size-min_size+3))
    end

    return found
end

