function setup_new_game()
  if hiscore ~= nil then    
    TFile = io.open("hiscore.txt","w")
    TFile:write("hiscore = "..hiscore)
    TFile:close()
    TFile = nil 
  end
  points = 0
  displayed_points = 0
  space_warp = 0
  in_wave = 0
  state = "title"
  playerx = 215
  playery = 200
  bulletx = {}
  bullety = {}
  bulletxv = {}
  bulletyv = {}
  bullet_wait_time = 0
  bullet_wait_time_max = 0
  bullets_to_be_removed = {}
  pad = Controls.read()
  old_pad = pad
  old_cross_down = pad:cross()
  chickenx = {}
  chickeny = {}
  chickenxv = {}
  chickenyv = {}
  chicken_type = {}
  chicken_move_direction = "right"
  level = 0
  chickens_on_level = 0
  level_cooldown_timer = 0
  chicken_move_speed = 2
  chickens_to_be_removed = {}
  chicken_angle = {}
  eggx = {}
  eggy = {}
  egg_move_speed = {}
  eggs_to_be_removed = {}
  egg_splatterx = {}
  egg_splattery = {}
  egg_splatter_time = {}
  egg_splatter_time_max = 30
  egg_splatter_to_be_removed = {}
  respawn_invin = 0
  explosion_particle_angle = {}
  explosion_particle_speed = {}
  explosion_particle_time = {}
  explosion_particlex = {}
  explosion_particley = {}
  explosion_particle_to_be_removed = {}
  rock_move_speed = {}
  chicken_health = {}
  re_run_amount = 0
  presentx = {}
  presenty = {}
  presents_to_be_removed = {}
  bullets_fired = 1
  lives = 3
  drum_sticksx = {}
  drum_sticksy = {}
  drum_sticks_to_be_removed = {}
end
setup_new_game()
yellow = Color.new(255,255,0)
white = Color.new(255,255,255)
math.randomseed(os.time())
title = Image.load("title.png")
sprites = Image.load("sprites.png")
bg = Image.load("bg.png")
bgy1 = -272
bgy2 = 0
player_move_speed = 5
bullet_move_speed = 5
dofile("hiscore.txt")





dofile("explosion.lua")
dofile("misc.lua")
dofile("levels.lua")
dofile("eggs.lua")
dofile("presents.lua")
dofile("drumsticks.lua")

function do_points()
  if points - displayed_points > 1000 then displayed_points = displayed_points + 200 end
  if points - displayed_points > 100 then displayed_points = displayed_points + 20 end
  if points - displayed_points > 10 then displayed_points = displayed_points + 2 end


  if displayed_points > points then displayed_points = points end
end

function next_level()
  for i = 1,chickens_on_level do
    table.insert(chickens_to_be_removed,i)
  end
  chickens_on_level = 0
  remove_chickens()
end

function scroll_background()
    bgy1 = bgy1 + 1 + (space_warp /50)
    bgy2 = bgy2 + 1 + (space_warp /50)
    if bgy1 >= 272 then bgy1 = bgy2-272 end
    if bgy2 >= 272 then bgy2 = bgy1-272 end
    screen:blit(0,bgy1,bg)
    screen:blit(0,bgy2,bg)
end

function move_player()
    tmp1 = false
    if pad:left() and not tmp1 and playerx > 2 then tmp1 = true playerx = playerx - player_move_speed end
    if pad:right() and not tmp1 and playerx < 435 then tmp1 = true playerx = playerx + player_move_speed end

    if respawn_invin > 0 then respawn() end
end

function respawn()
  respawn_invin = respawn_invin - 1
  if respawn_invin > 50 then
    playery = 200 + ((respawn_invin - 50) * 2)
  else
    playery = 200
  end
end

function remove_bullets()
  bullets_to_be_removed = sort(bullets_to_be_removed)
  if table.getn(bullets_to_be_removed) > 0 then
    for i = 1,table.getn(bullets_to_be_removed) do
      table.remove(bulletx,bullets_to_be_removed[i])
      table.remove(bullety,bullets_to_be_removed[i])
      table.remove(bulletxv,bullets_to_be_removed[i])
      table.remove(bulletyv,bullets_to_be_removed[i])
    end
  end
  bullets_to_be_removed = {}
end

function remove_chickens()
  if table.getn(chickens_to_be_removed) > 0 then
    chickens_to_be_removed = sort(chickens_to_be_removed)
    for i = 1,table.getn(chickens_to_be_removed) do
      i = (i * -1) + 1 + table.getn(chickens_to_be_removed)
      table.remove(chickenx,chickens_to_be_removed[i]) 
      table.remove(chickeny,chickens_to_be_removed[i]) 
      table.remove(chicken_type,chickens_to_be_removed[i]) 
      if table.getn(chicken_angle) > 0 then table.remove(chicken_angle,chickens_to_be_removed[i]) end
      if table.getn(rock_move_speed) > 0 then table.remove(rock_move_speed,chickens_to_be_removed[i]) end
      if table.getn(chicken_health) > 0 then table.remove(chicken_health,chickens_to_be_removed[i]) end
      if table.getn(chickenxv) > 0 then table.remove(chickenxv,chickens_to_be_removed[i]) end
      if table.getn(chickenyv) > 0 then table.remove(chickenyv,chickens_to_be_removed[i]) end

      chickens_on_level = chickens_on_level - 1
    end
  end
  chickens_to_be_removed = {}
end

function kill_things()

  if table.getn(presentx) > 0  then
    for i = 1,table.getn(presentx) do
      if collision(playerx+5,playery+5,43-10,45-10,presentx[i],presenty[i],18,26) then
        table.insert(presents_to_be_removed,i)
        bullets_fired = bullets_fired + 1
      end
    end
  end

  if respawn_invin <= 0 and chickens_on_level > 0 and (level == 3 or level == 6 or level == 7 or level == 8 or level == 9) then
    for i = 1,chickens_on_level do
      if collision(playerx+5,playery+5,43-10,45-10,chickenx[i],chickeny[i],37,30) then
        respawn_invin = 100
        lives = lives - 1
        create_explosion(playerx+20,playery+20,20)
      end
      if chickenx[i] > 480 or chickeny[i] > 272 then table.insert(chickens_to_be_removed,i) end
    end
  end

  if table.getn(eggx) > 0 and respawn_invin <= 0 then
    for i = 1,table.getn(eggx) do
      if collision(eggx[i],eggy[i],14,18,playerx+5,playery+5,43-10,45-10) then--player values are increased/decreased  by 2
        table.insert(eggs_to_be_removed,i)
        respawn_invin = 100
        lives = lives - 1
        create_explosion(playerx+20,playery+20,20)
      end
    end
  end






  if table.getn(drum_sticksx) > 0 and level ~= 3 and level ~= 6 and level ~= 9 then
    for i = 1,table.getn(drum_sticksx) do
      if collision(drum_sticksx[i],drum_sticksy[i],14,18,playerx+3,playery+3,43-6,45-6) then--player values are increased/decreased  by 2
        table.insert(drum_sticks_to_be_removed,i)
        points = points + 500
      end
    end
  end
  
  if level == 10 and table.getn(bulletx) > 0 and chickens_on_level > 0 then
    not_killed_chicken_yet = true
    for i = 1,table.getn(bulletx) do
      for o = 1,chickens_on_level do
        if not_killed_chicken_yet and not_inserted_yet(bullets_to_be_removed,i) and not_inserted_yet(chickens_to_be_removed,o) and (collision(bulletx[i],bullety[i],5,16,chickenx[o],chickeny[o],54,42) or collision(bulletx[i],bullety[i],5,16,chickenx[o],chickeny[o],101,111)) then 
          table.insert(bullets_to_be_removed,i)
          points = points + 100
          if chicken_health[o] <= 0 then
            points = points + 1000
            if math.random(5) == 1 then drop_present(o) end
            table.insert(chickens_to_be_removed,o)
            not_killed_chicken_yet = false
          else
            chicken_health[o] = chicken_health[o] - 1
          end
          create_explosion(chickenx[o]+50,chickeny[o]+50,10)
        end
      end
    end
  end
  
  if level ~= 10 and table.getn(bulletx) > 0 and chickens_on_level > 0 then
    not_killed_chicken_yet = true
    for i = 1,table.getn(bulletx) do
      for o = 1,chickens_on_level do
        if not_killed_chicken_yet and not_inserted_yet(bullets_to_be_removed,i) and not_inserted_yet(chickens_to_be_removed,o) and (collision(bulletx[i],bullety[i],5,16,chickenx[o],chickeny[o],54,42) or collision(bulletx[i],bullety[i],5,16,chickenx[o],chickeny[o],37,30)) then 
          table.insert(bullets_to_be_removed,i)
          points = points + 100
          if chicken_health[o] <= 0 then
            points = points + 300
            drop_drum_stick(o)
            if math.random(60) == 1 then drop_present(o) end
            table.insert(chickens_to_be_removed,o)
            not_killed_chicken_yet = false
          else
            chicken_health[o] = chicken_health[o] - 1
          end
          create_explosion(chickenx[o]+20,chickeny[o]+20,10)
        end
      end
    end
  end


  remove_bullets()
  remove_chickens()
end

function not_inserted_yet(table2,number)
  if table.getn(table2) > 0 then
    for i = 1,table.getn(table2) do
      if number == i then return false end
    end
  end
  return true
end

function draw_graphics()

  if table.getn(explosion_particle_angle) > 0 then
    for i = 1,table.getn(explosion_particle_angle) do
      if explosion_particlex[i] ~= nil then
        if explosion_particlex[i] > 5 and explosion_particlex[i] < 475 and explosion_particley[i] > 5 and explosion_particley[i] < 267 then
          screen:pixel(explosion_particlex[i],explosion_particley[i],yellow)
        end
      end
    end
  end

  if table.getn(bulletx) > 0 then
    for i = 1,table.getn(bulletx) do
      screen:blit(bulletx[i],bullety[i],sprites,26,91,5,16)
    end
  end

  if chickens_on_level > 0 then
    for i = 1,chickens_on_level do
      if chicken_type[i] == 1 then screen:blit(chickenx[i],chickeny[i],sprites,1,0,40,43) end
      if chicken_type[i] == 2 then screen:blit(chickenx[i],chickeny[i],sprites,46,0,43,42) end
      if chicken_type[i] == 3 then screen:blit(chickenx[i],chickeny[i],sprites,92,0,45,42) end
      if chicken_type[i] == 4 then screen:blit(chickenx[i],chickeny[i],sprites,140,0,49,40) end
      if chicken_type[i] == 5 then screen:blit(chickenx[i],chickeny[i],sprites,193,0,52,40) end
      if chicken_type[i] == 6 then screen:blit(chickenx[i],chickeny[i],sprites,249,0,54,39) end
      if chicken_type[i] == 7 then screen:blit(chickenx[i],chickeny[i],sprites,306,0,53,38) end

      if chicken_type[i] == 8 then screen:blit(chickenx[i],chickeny[i],sprites,306,0,53,38) end
      if chicken_type[i] == 9 then screen:blit(chickenx[i],chickeny[i],sprites,249,0,54,39) end
      if chicken_type[i] == 10 then screen:blit(chickenx[i],chickeny[i],sprites,193,0,52,40) end
      if chicken_type[i] == 11 then screen:blit(chickenx[i],chickeny[i],sprites,140,0,49,40) end
      if chicken_type[i] == 12 then screen:blit(chickenx[i],chickeny[i],sprites,92,0,45,42) end
      if chicken_type[i] == 13 then screen:blit(chickenx[i],chickeny[i],sprites,46,0,43,42) end
      if chicken_type[i] == 14 then screen:blit(chickenx[i],chickeny[i],sprites,1,0,40,43) end
      if chicken_type[i] == 16 then screen:blit(chickenx[i],chickeny[i],sprites,216,150,37,30) end

      if chicken_type[i] == 18 then screen:blit(chickenx[i],chickeny[i],sprites,359,0,101,111) end

      chicken_type[i] = chicken_type[i] + 1
      if chicken_type[i] == 15 then chicken_type[i] = 1 end
      if chicken_type[i] == 17 then chicken_type[i] = 16 end
      if chicken_type[i] == 19 then chicken_type[i] = 18 end
    end
  end

  tmp1 = false
  if pad:left() then screen:blit(playerx,playery,sprites,282,59,37,59) end
  if pad:right() and not pad:left() then screen:blit(playerx+7,playery,sprites,244,59,37,44) end
  if not pad:left() and not pad:right() then screen:blit(playerx,playery,sprites,200,58,43,45) end

  if table.getn(egg_splatterx) > 0 then
    for i = 1,table.getn(egg_splatterx) do
      screen:blit(egg_splatterx[i],egg_splattery[i],sprites,61,54,36,17)
    end
  end

  if table.getn(drum_sticksx) > 0 then
    for i = 1,table.getn(drum_sticksx) do
      screen:blit(drum_sticksx[i],drum_sticksy[i],sprites,20,52,10,21)
    end
  end

  if table.getn(eggx) > 0 then
    for i = 1,table.getn(eggx) do
      screen:blit(eggx[i],eggy[i],sprites,1,53,14,18)
    end
  end

  if table.getn(presentx) > 0 then
    for i = 1,table.getn(presentx) do
      screen:blit(presentx[i],presenty[i],sprites,121,163,18,26)
    end
  end
  
  if respawn_invin > 0 and respawn_invin ~= 100 then screen:blit(playerx-16,playery-16,sprites,109,51,76,76) end

  if level == 4 or level == 5 then screen:blit(202,50,sprites,0,121,77,76) end


  for i = 1, lives do
    screen:blit(480-(i*15),15,sprites,44,56,10,11)
  end

end

function shoot_bullet()
  if bullet_wait_time <= 0 then
    bullet_wait_time = bullet_wait_time_max
    





    if bullets_fired == 1 then
      create_bullet(19,-5,0,5)
    end

    if bullets_fired == 2 then
      create_bullet(10,-5,0,5)
      create_bullet(30,-5,0,5)
    end

    if bullets_fired == 3 then
      create_bullet(10,0,0,5)
      create_bullet(20,-10,0,5)
      create_bullet(30,0,0,5)
    end

    if bullets_fired == 4 then
      create_bullet(10,-5,-1,5)
      create_bullet(20,-5,0,5)
      create_bullet(30,-5,1,5)
    end

    if bullets_fired == 5 then
      create_bullet(10,-5,-1,5)
      create_bullet(15,-5,-0.5,5)
      create_bullet(25,-5,0.5,5)
      create_bullet(30,-5,1,5)
    end

    if bullets_fired == 6 then
      create_bullet(10,-5,-1,5)
      create_bullet(15,-5,-0.5,5)
      create_bullet(19,-5,0,5)
      create_bullet(25,-5,0.5,5)
      create_bullet(30,-5,1,5)
    end

    if bullets_fired == 7 then
      create_bullet(10,-5,-1,5)
      create_bullet(15,-5,-0.5,5)
      create_bullet(19,-5,-0.2,5)
      create_bullet(19,-5,0.2,5)
      create_bullet(25,-5,0.5,5)
      create_bullet(30,-5,1,5)
    end

    if bullets_fired >= 8 then
      create_bullet(10,-5,-1,5)
      create_bullet(15,-5,-0.5,5)
      create_bullet(19,-5,-0.2,5)
      create_bullet(19,-5,0,5)
      create_bullet(19,-5,0.2,5)
      create_bullet(25,-5,0.5,5)
      create_bullet(30,-5,1,5)
    end

  end
end

function move_bullets()
  if table.getn(bulletx) > 0 then
    for i = 1,table.getn(bulletx) do
      bullety[i] = bullety[i] - bulletyv[i]
      bulletx[i] = bulletx[i] + bulletxv[i]
      
      if bullety[i] <= - 10 then table.insert(bullets_to_be_removed,i) end
    end
  end
  remove_bullets()
end

function create_bullet(x1,y1,x2,y2)
    table.insert(bulletx,playerx + x1)
    table.insert(bullety,playery + y1)
    table.insert(bulletxv,x2)
    table.insert(bulletyv,y2)
end



while true do
  screen:clear()
  pad = Controls.read()
  
  if state == "title" then 
    screen:blit(0,0,title) 
    screen:print(480-(string.len(hiscore)*8)-72,0,"hiscore: "..hiscore,white)
    if pad:cross() and not old_cross_down then state = "play" old_cross_down = true end
  end
  if state == "play" then 
    if chickens_on_level < 0 then chickens_on_level = 0 end
    scroll_background()
    setup_levels()
    drop_eggs()
    move_presents()
    do_points()
    move_chickens()
    move_player()
    move_bullets()
    move_explosion()
    move_drum_sticks()
    kill_things()
    --if pad:r() then next_level() end
    --if pad:l() then bullets_fired = bullets_fired + 1 end
    if pad:cross() 
    and not old_cross_down  -- comment out this line for rapid fire! XD 
    then shoot_bullet() end
    bullet_wait_time = bullet_wait_time - 1
    
    draw_graphics()
    if lives <= 0 then if points>hiscore then hiscore = points end setup_new_game() end
    screen:print(480-(string.len(displayed_points)*8)-64,0,"points: "..displayed_points,white)
    screen:print(0,10,level,white)
  end
  old_pad = pad
  old_cross_down = pad:cross()

  screen.flip()
  screen.waitVblankStart(3)
end
