#using
import mwpy_dispatcher
import mwpy_gameobject
import mwpy_actor
import mwpy_static
import mwpy_bridge
import mwpy_lethal
import mwpy_group
import mwpy_lift
import mwpy_teleport
import mwpy_outteleport
import mwpy_portal
import mwpy_wall
import mwpy_monstr
import mwpy_collect
import mwpy_world
import mwpy_sprite
import mwpy_water
import mwpy_pipeline
import mwpy_pipelinegroup
import mwpy_windleft
import mwpy_windright
import mwpy_spring
import mwpy_switch
import mwpy_stone
import mwpy_gate
import mwpy_funnel
import mwpy_door
import mwpy_button
import mwpy_fountain
import sys

import time








#using namespace
clock = time.clock
MWPYStaticObject = mwpy_static.MWPYStaticObject
MWPYActor = mwpy_actor.MWPYActor
MWPYBridge = mwpy_bridge.MWPYBridge
MWPYLethal = mwpy_lethal.MWPYLethal
MWPYGroup = mwpy_group.MWPYGroup
MWPYLift = mwpy_lift.MWPYLift
MWPYTeleport = mwpy_teleport.MWPYTeleport
MWPYOutTeleport = mwpy_outteleport.MWPYOutTeleport
MWPYPortal = mwpy_portal.MWPYPortal
MWPYWall = mwpy_wall.MWPYWall
Dispatch = mwpy_dispatcher.Dispatch
MWPYWorld = mwpy_world.MWPYWorld
MWPYGameObjectState = mwpy_gameobject.MWPYGameObjectState
MWPYSprite = mwpy_sprite.MWPYSprite
MWPYMonstr = mwpy_monstr.MWPYMonstr
MWPYCollect = mwpy_collect.MWPYCollect
MWPYWater = mwpy_water.MWPYWater
MWPYPipeline = mwpy_pipeline.MWPYPipeline
MWPYPipelineGroup = mwpy_pipelinegroup.MWPYPipelineGroup
MWPYWindLeft = mwpy_windleft.MWPYWindLeft
MWPYWindRight = mwpy_windright.MWPYWindRight
MWPYSpring = mwpy_spring.MWPYSpring
MWPYSwitch = mwpy_switch.MWPYSwitch
MWPYStone = mwpy_stone.MWPYStone
MWPYGate = mwpy_gate.MWPYGate
MWPYFunnel = mwpy_funnel.MWPYFunnel
MWPYDoor = mwpy_door.MWPYDoor
MWPYButton = mwpy_button.MWPYButton
MWPYFountain = mwpy_fountain.MWPYFountain

getGameObjectStateStr = mwpy_gameobject.getGameObjectStateStr
MWPYGameObjectType = mwpy_gameobject.MWPYGameObjectType

def create(name):
    o = None
    if name == "MWGOT_SIMPLE": o = MWPYStaticObject()
    elif name == "MWGOT_ACTOR": o = MWPYActor()
    elif name == "MWGOT_BRIDGE": o = MWPYBridge()
    elif name == "MWGOT_LETHAL": o = MWPYLethal()
    elif name == "MWGOT_GROUP": o = MWPYGroup()
    elif name == "MWGOT_LIFT": o = MWPYLift()
    elif name == "MWGOT_TELEPORT": o = MWPYTeleport()
    elif name == "MWGOT_OUTTELEPORT": o = MWPYOutTeleport()
    elif name == "MWGOT_PORTAL": o = MWPYPortal()
    elif name == "MWGOT_WALL": o = MWPYWall()
    elif name == "MWGOT_MONSTR": o = MWPYMonstr()
    elif name == "MWGOT_COLLECT": o = MWPYCollect()
    elif name == "MWGOT_WATER": o = MWPYWater()
    elif name == "MWGOT_PIPELINE": o = MWPYPipeline()
    elif name == "MWGOT_PIPELINEGROUP": o = MWPYPipelineGroup()
    elif name == "MWGOT_WINDLEFT": o = MWPYWindLeft()
    elif name == "MWGOT_WINDRIGHT": o = MWPYWindRight() 
    elif name == "MWGOT_SPRING": o = MWPYSpring()
    elif name == "MWGOT_SWITCH": o = MWPYSwitch()
    elif name == "MWGOT_STONE": o = MWPYStone()
    elif name == "MWGOT_GATE": o = MWPYGate()
    elif name == "MWGOT_FUNNEL": o = MWPYFunnel()
    elif name == "MWGOT_DOOR": o = MWPYDoor()
    elif name == "MWGOT_BUTTON": o = MWPYButton()
    elif name == "MWGOT_FOUNTAIN": o = MWPYFountain()      
    return o
        
def create_dispatcher():
    d = Dispatch()
    d.add_rule(MWPYActor, MWPYActor, HandlerActorActor)
    d.add_rule(MWPYActor, MWPYStaticObject, HandlerActorSimple)
    d.add_rule(MWPYStaticObject, MWPYActor, HandlerActorSimple)
    d.add_rule(MWPYActor, MWPYGroup, HandlerActorSimple)
    d.add_rule(MWPYGroup, MWPYActor, HandlerActorSimple)
    d.add_rule(MWPYGroup, MWPYTeleport, HandlerSimple);
    d.add_rule(MWPYTeleport, MWPYGroup, HandlerSimple);
    d.add_rule(MWPYStaticObject, MWPYTeleport, HandlerSimple);
    d.add_rule(MWPYTeleport, MWPYStaticObject, HandlerSimple);
    d.add_rule(MWPYActor, MWPYTeleport, HandlerActorTeleport)
    d.add_rule(MWPYTeleport, MWPYActor, HandlerActorTeleport)
    d.add_rule(MWPYMonstr, MWPYTeleport, HandlerActorTeleport)
    d.add_rule(MWPYTeleport, MWPYMonstr, HandlerActorTeleport)
    d.add_rule(MWPYStone, MWPYTeleport, HandlerActorTeleport)
    d.add_rule(MWPYTeleport, MWPYStone, HandlerActorTeleport)
    d.add_rule(MWPYActor, MWPYLift, HandlerActorLift)
    d.add_rule(MWPYLift, MWPYActor, HandlerActorLift)
    d.add_rule(MWPYBridge, MWPYGroup, HandlerBridgeSimple)
    d.add_rule(MWPYGroup, MWPYBridge, HandlerBridgeSimple)
    d.add_rule(MWPYBridge, MWPYStaticObject, HandlerBridgeSimple)
    d.add_rule(MWPYStaticObject, MWPYBridge, HandlerBridgeSimple)
    d.add_rule(MWPYActor, MWPYBridge, HandlerActorBridge)
    d.add_rule(MWPYBridge, MWPYActor, HandlerActorBridge)
    d.add_rule(MWPYMonstr, MWPYBridge, HandlerActorBridge)
    d.add_rule(MWPYBridge, MWPYMonstr, HandlerActorBridge)
    d.add_rule(MWPYStone, MWPYBridge, HandlerActorBridge)
    d.add_rule(MWPYBridge, MWPYStone, HandlerActorBridge)
    d.add_rule(MWPYActor, MWPYPortal, HandlerActorPortal)
    d.add_rule(MWPYPortal, MWPYActor, HandlerActorPortal)
    d.add_rule(MWPYMonstr, MWPYStaticObject, HandlerMonstrSimple)
    d.add_rule(MWPYStaticObject, MWPYMonstr, HandlerMonstrSimple)
    d.add_rule(MWPYMonstr, MWPYGroup, HandlerMonstrSimple)
    d.add_rule(MWPYGroup, MWPYMonstr, HandlerMonstrSimple)
    d.add_rule(MWPYStone, MWPYStaticObject, HandlerMonstrSimple)
    d.add_rule(MWPYStaticObject, MWPYStone, HandlerMonstrSimple)
    d.add_rule(MWPYStone, MWPYGroup, HandlerMonstrSimple)
    d.add_rule(MWPYGroup, MWPYStone, HandlerMonstrSimple)
    d.add_rule(MWPYWall, MWPYStaticObject, HandlerWallSimple)
    d.add_rule(MWPYStaticObject, MWPYWall, HandlerWallSimple)
    d.add_rule(MWPYWall, MWPYGroup, HandlerWallSimple)
    d.add_rule(MWPYGroup, MWPYWall, HandlerWallSimple)
    d.add_rule(MWPYWall, MWPYMonstr, HandlerSimple)
    d.add_rule(MWPYMonstr, MWPYWall, HandlerSimple)
    d.add_rule(MWPYWall, MWPYStone, HandlerSimple)
    d.add_rule(MWPYStone, MWPYWall, HandlerSimple)
    d.add_rule(MWPYActor, MWPYWall, HandlerActorWall)
    d.add_rule(MWPYWall, MWPYActor, HandlerActorWall)
    d.add_rule(MWPYMonstr, MWPYWall, HandlerActorWall)
    d.add_rule(MWPYWall, MWPYMonstr, HandlerActorWall)
    d.add_rule(MWPYMonstr, MWPYActor, HandlerMonstrActor)
    d.add_rule(MWPYActor, MWPYMonstr, HandlerMonstrActor)
    d.add_rule(MWPYStone, MWPYActor, HandlerMonstrActor)
    d.add_rule(MWPYActor, MWPYStone, HandlerMonstrActor)
    d.add_rule(MWPYLethal, MWPYActor, HandlerActorLethal)
    d.add_rule(MWPYActor, MWPYLethal, HandlerActorLethal)
    d.add_rule(MWPYCollect, MWPYActor, HandlerActorCollect)
    d.add_rule(MWPYActor, MWPYCollect, HandlerActorCollect)
    d.add_rule(MWPYWater, MWPYActor, HandlerActorWater)
    d.add_rule(MWPYActor, MWPYWater, HandlerActorWater)
    d.add_rule(MWPYWater, MWPYMonstr, HandlerActorWater)
    d.add_rule(MWPYMonstr, MWPYWater, HandlerActorWater)    
    d.add_rule(MWPYWater, MWPYTeleport, HandlerTeleportWater)
    d.add_rule(MWPYTeleport, MWPYWater, HandlerTeleportWater)
    d.add_rule(MWPYWater, MWPYStone, HandlerStoneWater)
    d.add_rule(MWPYStone, MWPYWater, HandlerStoneWater)
    d.add_rule(MWPYPipelineGroup, MWPYActor, HandlerActorPipeline)
    d.add_rule(MWPYActor, MWPYPipelineGroup, HandlerActorPipeline)
    d.add_rule(MWPYPipelineGroup, MWPYStone, HandlerMonstrSimple)
    d.add_rule(MWPYStone, MWPYPipelineGroup, HandlerMonstrSimple)
    d.add_rule(MWPYPipelineGroup, MWPYMonstr, HandlerSimple)
    d.add_rule(MWPYMonstr, MWPYPipelineGroup, HandlerSimple)
    d.add_rule(MWPYPipelineGroup, MWPYWall, HandlerWallSimple)
    d.add_rule(MWPYWall, MWPYPipelineGroup, HandlerWallSimple)
    d.add_rule(MWPYPipelineGroup, MWPYTeleport, HandlerSimple);
    d.add_rule(MWPYTeleport, MWPYPipelineGroup, HandlerSimple);
    d.add_rule(MWPYSpring, MWPYActor, HandlerActorSpring)
    d.add_rule(MWPYActor, MWPYSpring, HandlerActorSpring)
    d.add_rule(MWPYSpring, MWPYStone, HandlerActorSpring)
    d.add_rule(MWPYStone, MWPYSpring, HandlerActorSpring)
    d.add_rule(MWPYSwitch, MWPYActor, HandlerActorSwitch)
    d.add_rule(MWPYActor, MWPYSwitch, HandlerActorSwitch)
    d.add_rule(MWPYStone, MWPYMonstr, HandlerStoneMonstr)
    d.add_rule(MWPYMonstr, MWPYStone, HandlerStoneMonstr)
    d.add_rule(MWPYGate, MWPYActor, HandlerActorGate)
    d.add_rule(MWPYActor, MWPYGate, HandlerActorGate)
    d.add_rule(MWPYGate, MWPYStone, HandlerStoneGate)
    d.add_rule(MWPYStone, MWPYGate, HandlerStoneGate)
    d.add_rule(MWPYFunnel, MWPYGroup, HandlerSimple)
    d.add_rule(MWPYGroup, MWPYFunnel, HandlerSimple)
    d.add_rule(MWPYFunnel, MWPYStaticObject, HandlerSimple)
    d.add_rule(MWPYStaticObject, MWPYFunnel, HandlerSimple)
    d.add_rule(MWPYFunnel, MWPYPipelineGroup, HandlerSimple)
    d.add_rule(MWPYPipelineGroup, MWPYFunnel, HandlerSimple)
    d.add_rule(MWPYFunnel, MWPYActor, HandlerActorFunnel)
    d.add_rule(MWPYActor, MWPYFunnel, HandlerActorFunnel)
    d.add_rule(MWPYDoor, MWPYActor, HandlerActorDoor)
    d.add_rule(MWPYActor, MWPYDoor, HandlerActorDoor)
    d.add_rule(MWPYButton, MWPYActor, HandlerActorButton)
    d.add_rule(MWPYActor, MWPYButton, HandlerActorButton)
    d.add_rule(MWPYActor, MWPYFountain, HandlerActorFountain)
    d.add_rule(MWPYFountain, MWPYActor, HandlerActorFountain)
    d.add_rule(MWPYMonstr, MWPYFountain, HandlerActorFountain)
    d.add_rule(MWPYFountain, MWPYMonstr, HandlerActorFountain)
    d.add_rule(MWPYWater, MWPYButton, HandlerButtonWater)
    d.add_rule(MWPYButton, MWPYWater, HandlerButtonWater)
    d.add_rule(MWPYStaticObject, MWPYButton, HandlerSimple)
    d.add_rule(MWPYButton, MWPYStaticObject, HandlerSimple)
    d.add_rule(MWPYGroup, MWPYButton, HandlerSimple)
    d.add_rule(MWPYButton, MWPYGroup, HandlerSimple)
    d.add_rule(MWPYPipelineGroup, MWPYButton, HandlerSimple)
    d.add_rule(MWPYButton, MWPYPipelineGroup, HandlerSimple)
    d.add_rule(MWPYWater, MWPYFountain, HandlerFountainWater)
    d.add_rule(MWPYFountain, MWPYWater, HandlerFountainWater)
    d.add_rule(MWPYWall, MWPYWater, HandlerWallWater)
    d.add_rule(MWPYWater, MWPYWall, HandlerWallWater)
    return d

def create_sprite_info(name, posx, posy, width, height, tex_x, tex_y, tex_w, tex_h, enable, flip_h, flip_v, anim_inv, x_scale_factor, y_scale_factor):
    si = MWPYSprite()
    si.name = name
    si.posx = posx
    si.posy = posy
    si.width = width
    si.height = height
    si.tex_x = tex_x
    si.tex_y = tex_y
    si.tex_w = tex_w
    si.tex_h = tex_h
    si.enable = enable
    si.flip_h = flip_h
    si.flip_v = flip_v
    si.anim_inv = anim_inv
    si.x_scale_factor = x_scale_factor
    si.y_scale_factor = y_scale_factor
    return si

def process_tool(obj_coll_dict, go_type, centx, centy, width, height):
    if(go_type in obj_coll_dict):
        li = obj_coll_dict[go_type]
        for obj in li:
            if obj.gameObjectType == go_type:
                if obj.is_enable != True:
                    obj.enable()
                    if(go_type == MWPYGameObjectType['MWGOT_BRIDGE']):
                        if(width > 0.075):
                               width = 0.075
                        obj.x = centx - width 
                        obj.y = centy - obj.h * 0.5
                        obj.w = width * 2

                    else:
                        obj.x = centx - obj.w * 0.5
                        obj.y = centy - obj.h * 0.5
                    return True
    return False

                    
def is_done(obj_coll_dict):
    #exit criteria for bonus level
    collectType = MWPYGameObjectType['MWGOT_COLLECT']
    if collectType in obj_coll_dict:
        isThereAnyBonusEnable = False
        collects = obj_coll_dict[collectType]
        for collect in collects:
            if (collect.is_enable == True):
                isThereAnyBonusEnable = True
        if (isThereAnyBonusEnable == False):
            return True
                
    actorType = MWPYGameObjectType['MWGOT_ACTOR']
    #check for freeze (last level)
    if actorType in obj_coll_dict:
        actors = obj_coll_dict[actorType]
        is_any_freeze = True
        for actor in actors:
            if actor.isfreeze == False and actor.islife == True:
                is_any_freeze = False
        if is_any_freeze == True:
            return True
            
    if actorType in obj_coll_dict:
        actors = obj_coll_dict[actorType]
        is_any_life = False
        for actor in actors:
            if actor.is_enable == True:
                return False
            if actor.islife == True:
                is_any_life = True
    if is_any_life == False: return False
    protalType = MWPYGameObjectType['MWGOT_PORTAL']
    if protalType in obj_coll_dict:
        portals = obj_coll_dict[protalType]
        for portal in portals:
            if portal.state != MWPYGameObjectState['AS_NONE']:
                return False

    
    return True


def is_failed(obj_coll_dict):
    actorType = MWPYGameObjectType['MWGOT_ACTOR']
    if actorType in obj_coll_dict:
        actors = obj_coll_dict[actorType]
        for actor in actors:
            if actor.islife == True:
                return False
    return True

def HandlerSimple(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    return True

def HandlerActorActor(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    return False

def HandlerActorSimple(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYActor):
        actor = obj1
        obj = obj2
    else:
        actor = obj2
        obj = obj1
    if(actor.state == MWPYGameObjectState['AS_UP']):
        return False
    if(obj.name.find("Freezer") != -1):
        actor.freeze()
        actor.life_time = clock() - actor.start_time
    pixel_height = 1 / 732.0
    if (normx != 0):
        step_height = actor.y + actor.h + actor.h - obj.y
        if (step_height < (20.0 * pixel_height)):
            actor.y = actor.y - step_height
            return False
    if(normy != 0 and actor.state == MWPYGameObjectState['AS_DOWN']):
        actor.vel_y = 0
    return True

def HandlerActorTeleport(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYActor):
        actor = obj1
        telep = obj2
    else:
        actor = obj2
        telep = obj1
    if (depth > 0.06):
        out_telep_type = MWPYGameObjectType['MWGOT_OUTTELEPORT']
        if(out_telep_type in world_dict):
            for out_telep in world_dict[out_telep_type]:
                actor.x = out_telep.x
                actor.y = out_telep.y
                actor.state = MWPYGameObjectState[out_telep.out_actor_status]
                if (actor.state == MWPYGameObjectState['AS_LEFT']):
                    actor.vel_x = -actor.velocity_factor
                else:
                    actor.vel_x = actor.velocity_factor
        dispatch.sound_fx = 'TeleGo'
    return False

def HandlerActorLift(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYActor):
        actor = obj1
        lift = obj2
    else:
        actor = obj2
        lift = obj1
    if actor.state == MWPYGameObjectState['AS_DOWN']:
        return False
    if(depth >= 0.01):
        actor.state = MWPYGameObjectState['AS_UP']
        actor.vel_x = 0
        actor.vel_y = -actor.velocity_factor
        actor.x = lift.x + lift.w - actor.w
    elif(depth >= 0.002):
        if(actor.y < lift.y):
            actor.vel_x = 0
            actor.vel_y = -actor.velocity_factor
    else:
        if(actor.state == MWPYGameObjectState['AS_UP']):
            actor.state = MWPYGameObjectState[lift.out_actor_status]
            if(lift.out_actor_status == 'AS_LEFT'):
                actor.vel_x = -actor.velocity_factor
            else:
                actor.vel_x = actor.velocity_factor

    return False

def HandlerBridgeSimple(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYBridge):
        bridge = obj1
        simple = obj2
    else:
        bridge = obj2
        simple = obj1

    if(bridge.state == MWPYGameObjectState['AS_DOWN']):
        if(simple.y < bridge.y):
               bridge.y =  simple.y
               bridge.state = MWPYGameObjectState['AS_NONE']
               #bridge.gravity_action = False
    return False

def HandlerActorBridge(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if obj2.gameObjectType == MWPYGameObjectType['MWGOT_BRIDGE']:
        actor = obj1
        bridge = obj2
    else:
        actor = obj2
        bridge = obj1
    if actor.state == MWPYGameObjectState['AS_UP'] or bridge.state == MWPYGameObjectState['AS_DOWN'] or (actor.y + actor.h) > bridge.y:
        return False
    bridge.state = MWPYGameObjectState['AS_PLAY']
    bridge.contact_actor_time = bridge.current_time
    pixel_height = 1 / 732.0
    if (normx != 0):
        step_height = actor.y + actor.h + actor.h - bridge.y
        if (step_height < (20.0 * pixel_height)):
            actor.y = actor.y - step_height
            return False
    return True


def HandlerActorPortal(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYActor):
        actor = obj1
        portal = obj2
    else:
        actor = obj2
        portal = obj1
    if(depth > 0.08):
        actor.is_enable = False
        actor.life_time = clock() - actor.start_time
        portal.state = MWPYGameObjectState['AS_PLAY']
        portal.current_time = clock()
        dispatch.sound_fx = 'Portal'
    return False

def HandlerMonstrSimple(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYMonstr):
        monstr = obj1
        obj = obj2
    else:
        monstr = obj2
        obj = obj1
    pixel_height = 1 / 732.0
    if(obj.name.find("Freezer") != -1):
        monstr.freeze()
    if (normx != 0):
        step_height = monstr.y + monstr.h + monstr.h - obj.y
        if (step_height < (20.0 * pixel_height)):
            monstr.y = monstr.y - step_height
            return False
    return True
    
def HandlerMonstrActor(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if obj1.gameObjectType == MWPYGameObjectType['MWGOT_ACTOR']:
        actor = obj1
        monstr = obj2
    else:
        actor = obj2
        monstr = obj1
    actor.kill()
    dispatch.sound_fx = 'Kill'
    return False

def HandlerWallSimple(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYWall):
        wall = obj1
        obj = obj2
    else:
        wall = obj2
        obj = obj1
    if(wall.state == MWPYGameObjectState['AS_DOWN']):
        wall.state = MWPYGameObjectState['AS_PLAY']
        wall.y = obj.y - wall.h - wall.h
        wall.dust_play_time = wall.current_time
    return True

def HandlerActorWall(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYWall):
        wall = obj1
        obj = obj2
    else:
        wall = obj2
        obj = obj1
    if(wall.state == MWPYGameObjectState['AS_DOWN']):
        return False
    return True

def HandlerActorLethal(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYActor):
        actor = obj1
        obj = obj2
    else:
        actor = obj2
        obj = obj1
    actor.kill()
    dispatch.sound_fx = 'Kill'
    return False

def HandlerActorCollect(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYActor):
        actor = obj1
        collect = obj2
    else:
        actor = obj2
        collect = obj1
    if (depth > actor.w):
        collect.disable()
        dispatch.sound_fx = 'Tooth'
    return False


def HandlerActorWater(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYActor):
        actor = obj1
        water = obj2
    else:
        actor = obj2
        water = obj1
    h = (actor.h + actor.h)
    d = abs(actor.y - water.y)
    if(actor.vel_y > 0.6):
         actor.vel_y = 0.6
    if(depth < 0.01):
        actor.vel_y = actor.vel_y * 0.85
    if(depth < 0.002 and actor.vel_y < 0):
        actor.vel_y = actor.vel_y * 0.08
    percent = d / h + 1.0
    actor.frc_y = -0.99 * percent
    return False

def HandlerTeleportWater(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYTeleport):
        actor = obj1
        water = obj2
    else:
        actor = obj2
        water = obj1
    h = (actor.h + actor.h)
    d = abs(actor.y - water.y)
    if(actor.vel_y > 0.3):
         actor.vel_y = 0.3
    if(depth < 0.01):
        actor.vel_y = actor.vel_y * 0.85
    if(depth < 0.002 and actor.vel_y < 0):
        actor.vel_y = actor.vel_y * 0.05
    percent = d / h + 1.0
    actor.frc_y = -0.99 * percent
    return False

def HandlerActorPipeline(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYActor):
        actor = obj1
        obj = obj2
    else:
        actor = obj2
        obj = obj1

    if(actor.state == MWPYGameObjectState['AS_UP']):
          return False
    pixel_height = 1 / 896.0
    if (normx != 0): #and depth > 0.0004):
        step_height = actor.y + actor.h + actor.h - obj.y
        if (step_height < (8.0 * pixel_height)):
            actor.y = actor.y - step_height
            return False
    if (normy != 0):
        if(actor.y < obj.y):
            actor.state = MWPYGameObjectState[obj.out_actor_status]
            if(actor.state == MWPYGameObjectState['AS_LEFT']):
                actor.frc_x = actor.frc_x - 12.5
            else:
                actor.frc_x = actor.frc_x + 12.5
    return True

def HandlerActorSpring(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYActor):
        actor = obj1
        spring = obj2
    else:
        actor = obj2
        spring = obj1
    if spring.state == MWPYGameObjectState['AS_PLAY']:
        if (actor.y + actor.h + actor.h - depth - depth) < spring.y:
            actor.frc_y  = actor.frc_y + spring.force_y
            actor.frc_x  = actor.frc_x + spring.force_x
            dispatch.sound_fx = 'Spring'
            return False
    return True

def HandlerActorSwitch(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYActor):
        actor = obj1
        switch = obj2
    else:
        actor = obj2
        switch = obj1
    if switch.state == MWPYGameObjectState['AS_LEFT']:
        switch.state =  MWPYGameObjectState['AS_RIGHT']
        spring_type = MWPYGameObjectType['MWGOT_SPRING']
        if(spring_type in world_dict):
            for spring in world_dict[spring_type]:
                spring.switchon()
        gate_type = MWPYGameObjectType['MWGOT_GATE']
        if(gate_type in world_dict):
            for gate in world_dict[gate_type]:
                gate.switchon()
        door_type = MWPYGameObjectType['MWGOT_DOOR']
        if(door_type in world_dict):
            for door in world_dict[door_type]:
                door.open()
        dispatch.sound_fx = 'Switch'
          
    return False

def HandlerStoneMonstr(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if obj1.gameObjectType == MWPYGameObjectType['MWGOT_MONSTR']:
        monstr = obj1
        stone = obj2
    else:
        monstr = obj2
        stone = obj1
    monstr.kill()
    dispatch.sound_fx = 'Kill'
    return False

def HandlerActorGate(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if obj1.gameObjectType == MWPYGameObjectType['MWGOT_ACTOR']:
        actor = obj1
        gate = obj2
    else:
        actor = obj2
        gate = obj1
    if gate.state != MWPYGameObjectState['AS_LEFT']: # RIGHT or PLAY
        gate.state = MWPYGameObjectState['AS_PLAY']
        bigwatertype =  MWPYGameObjectType['MWGOT_WATER']
        if(bigwatertype in world_dict):
            for bigwater in world_dict[bigwatertype]:
                if bigwater.y > gate.up_border and gate.step > 0 and (gate.bigwater_id == bigwater.id or 0 == gate.bigwater_id):
                    gate.last_contact_time = clock()
                    bigwater.y -= 0.001 * gate.step
                    bigwater.h += 0.0005 * gate.step
                    dispatch.sound_fx = 'Gate'
                elif bigwater.y < gate.up_border and gate.step < 0 and (gate.bigwater_id == bigwater.id or 0 == gate.bigwater_id):
                    gate.last_contact_time = clock()
                    bigwater.y -= 0.001 * gate.step
                    bigwater.h += 0.0005 * gate.step
                    dispatch.sound_fx = 'Gate'
        
    return False
                
def HandlerStoneWater(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj2, MWPYWater):
        stone = obj1
        water = obj2
    else:
        stone = obj2
        water = obj1
    h = (stone.h + stone.h)
    d = abs(stone.y - water.y)
    if(stone.vel_y > 0.15):
         stone.vel_y = 0.15
    return False

def HandlerStoneGate(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if obj2.gameObjectType == MWPYGameObjectType['MWGOT_GATE']:
        stone = obj1
        gate = obj2
    else:
        stone = obj2
        gate = obj1
    if gate.state != MWPYGameObjectState['AS_LEFT']: # RIGHT or PLAY
        gate.state = MWPYGameObjectState['AS_PLAY']
        bigwatertype =  MWPYGameObjectType['MWGOT_WATER']
        if(bigwatertype in world_dict):
            for bigwater in world_dict[bigwatertype]:
                if bigwater.y > gate.up_border and (gate.bigwater_id == bigwater.id or 0 == gate.bigwater_id):
                    gate.last_contact_time = clock()
                    bigwater.y -= 0.001 * gate.step
                    bigwater.h += 0.0005 * gate.step
    return False
                  
def HandlerActorFunnel(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYFunnel):
        funnel = obj1
        actor = obj2
    else:
        funnel = obj2
        actor = obj1
    ap = 1.0
    if actor.vel_x >= 0:
        windrighttype =  MWPYGameObjectType['MWGOT_WINDRIGHT']
        if(windrighttype in world_dict):
            for windright in world_dict[windrighttype]:
                if windright.is_enable and abs(windright.x - funnel.x) < 0.3:
                    ap += 1.5
    else:
           windlefttype =  MWPYGameObjectType['MWGOT_WINDLEFT']
           if(windlefttype in world_dict):
               for windleft in world_dict[windlefttype]:
                   if windleft.is_enable and abs(windleft.x - funnel.x) < 0.3:
                       ap += 1.5 
    if actor.y < funnel.y:# - funnel.h * 0.5:
        actor.frc_y  = actor.frc_y + funnel.force_y * ap
    dispatch.sound_fx = 'Funnel'
    return False

def HandlerActorDoor(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYDoor):
        door = obj1
        actor = obj2
    else:
        door = obj2
        actor = obj1
    if door.state == MWPYGameObjectState['AS_CLOSE']:
        return True
    return False

def HandlerActorButton(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYButton):
        button = obj1
        actor = obj2
    else:
        button = obj2
        actor = obj1
    button.push(world_dict)
    dispatch.sound_fx = 'Fountain'
    return False

def HandlerActorFountain(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYActor):
        actor = obj1
        fountain = obj2
    else:
        actor = obj2
        fountain = obj1

    if fountain.state == MWPYGameObjectState['AS_PLAY']:
        actor.frc_y  = actor.frc_y + fountain.force_y
        actor.frc_x  = actor.frc_x + fountain.force_x
    return False

def HandlerButtonWater(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYButton):
        button = obj1
        water = obj2
    else:
        button = obj2
        water = obj1
    h = (button.h + button.h)
    d = abs(button.y - water.y)
    if(button.vel_y > 0.3):
         button.vel_y = 0.3
    if(depth < 0.01):
        button.vel_y = button.vel_y * 0.85
    if(depth < 0.002 and button.vel_y < 0):
        button.vel_y = button.vel_y * 0.05
    percent = d / h + 1.0
    button.frc_y = -0.99 * percent
    return False

def HandlerFountainWater(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYFountain):
        fount = obj1
        water = obj2
    else:
        fount = obj2
        water = obj1
    h = (fount.h + fount.h)
    d = abs(fount.y - water.y)
    if(fount.vel_y > 0.3):
         fount.vel_y = 0.3
    if(depth < 0.01):
        fount.vel_y = fount.vel_y * 0.85
    if(depth < 0.002 and fount.vel_y < 0):
        fount.vel_y = fount.vel_y * 0.05
    percent = d / h + 1.0
    fount.frc_y = -0.99 * percent
    return False

def HandlerWallWater(obj1, obj2, posx, posy, depth, normx, normy, world_dict, dispatch):
    if isinstance(obj1, MWPYWall):
        wall = obj1
        water = obj2
    else:
        wall = obj2
        water = obj1
    h = (wall.h + wall.h)
    d = abs(wall.y - water.y)
    if(wall.vel_y > 0.3):
         wall.vel_y = 0.3
    percent = d / h + 1.0
    wall.frc_y *= 0.98
    return False
