#!/usr/bin/env python2.5

import gtk
import sys
import time
import pango

# Threadi tai gobject EI MOLEMMAT
#thread_in_use = False
#import gobject

thread_in_use = True
from Saie import ThreadThatRunsTheGame

from Point import Point
from Table import Table
from Ball import Ball
from Stick import Stick
from Player import Player
from Sight import Sight


# Gtk tai Hildon EI MOLEMMAT
import hildon
import osso  
maemo_enviroment = True
class Pool(hildon.Program) :

#maemo_enviroment = False
#class Pool :

   user_interface_description = """<ui>
   <menubar name="MenuBar">
     <menu action="File">
       <menuitem action="Restart"/>
       <menuitem action="Quit"/>
     </menu>
   </menubar>
   </ui>"""

   def __init__( self ) :
      if maemo_enviroment == True :
         hildon.Program.__init__(self)
         #osso_c = osso.Context("org.maemo.pool", "1.0.0", True)
         self.application_window = hildon.Window()
      else :
         self.application_window = gtk.Window( gtk.WINDOW_TOPLEVEL )

      self.application_window.set_title( "Pool" )
      self.application_window.connect( "destroy", self.exit_this_application )

      # MENU
      # Create a ui_manager instance
      ui_manager = gtk.UIManager()

      # Add the accelerator group to the toplevel window
      accelerator_group = ui_manager.get_accel_group()
      self.application_window.add_accel_group( accelerator_group )

      # Create an ActionGroup
      self.action_group = gtk.ActionGroup("GUIApplicationExample")

      # Create an ActionGroup
      self.action_group = gtk.ActionGroup("GUIApplicationExample")
      self.action_group.add_actions([( "File", None, "_File" ),
                                     ("Restart", None, "_Restart", "<Control>R",
                                      "Restart the Program", self.restart_this_application),
                                     ("Quit", None, "_Quit", "<Control>Q",
                                      "Quit the Program", self.exit_this_application)])

      # Add the action_group to the ui_manager
      ui_manager.insert_action_group(self.action_group, 0)

      # Add a UI description
      ui_manager.add_ui_from_string(self.user_interface_description)

      # Create a MenuBar
      menu_bar = ui_manager.get_widget("/MenuBar")

      if maemo_enviroment == True :
         hildon_style_menu  =  gtk.Menu()

         for menu_component in menu_bar.get_children() :

            menu_component.reparent( hildon_style_menu )

         self.application_window.set_menu( hildon_style_menu )

         menu_bar.destroy()

      # PIIRTOALUE
      self.drawing_area = gtk.DrawingArea()
      self.drawing_area.set_size_request(696, 396)

      self.drawing_area.connect("expose-event", self.drawing_area_exposed)

      self.drawing_area.connect("button_press_event",
                                 self.mouse_button_pressed)

      self.drawing_area.connect("motion_notify_event",
                                 self.mouse_motion_notified)

      self.drawing_area.connect("button_release_event",
                                 self.mouse_button_released)

      self.drawing_area.set_events(gtk.gdk.EXPOSURE_MASK
                                 | gtk.gdk.BUTTON_PRESS_MASK
                                 | gtk.gdk.POINTER_MOTION_MASK
                                 | gtk.gdk.POINTER_MOTION_HINT_MASK
                                 | gtk.gdk.BUTTON_RELEASE_MASK )

      self.mouse_x  =  0
      self.mouse_y  =  0
      self.must_shoot = False
      self.strength = 0

      self.change_player = False

      self.start_game()

      if maemo_enviroment == True :
         self.application_window.add(self.drawing_area)
      else :
         vbox = gtk.VBox(False, 1)
         self.application_window.add(vbox)
         vbox.pack_start(menu_bar, False, True, 0)
         vbox.pack_start(self.drawing_area, False, True, 0)

      self.application_window.show_all()

      self.callback_is_running = False
      self.callback = True

      if thread_in_use == True :
         self.thread_that_runs_the_game  =  ThreadThatRunsTheGame(self)
         self.thread_that_runs_the_game.start()
      else :
         gobject.timeout_add (30, self.callback_function)

   def callback_function(self):

      if self.callback_is_running == False :
         self.play_game()

      if self.callback == True :
         return True
      return False

   def start_game(self) :

      self.button_pressed_time = 0
      self.sight_is_changed = False
      self.change_player = False
      self.free_ball = False
      self.first_time_free_ball = True
      self.is_shooted = False
      self.ball_is_moving = False
      self.player = 1
      self.waiter = 2
      self.winner = 0

      # LUODAAN POYTA ANNETTUIHIN KOORDINAATTEIHIN
      self.table = Table(20, 60)
      self.stick = Stick()

      # LUODAAN TAHTAIN
      self.sight = Sight(600, 15)

      # LUODAAN PALLOPAKKA SEKA ASETETAAN PALLOT POINT-LUOKAN AVULLA

      p = Point(240, 220)

      self.balls = []

      self.balls += [Ball(p.x, p.y, gtk.gdk.Color(63222, 53970, 2570, 0), 1)]

      self.balls += [Ball(p.x - 17, p.y - 10, gtk.gdk.Color(10280, 1542, 51658, 0), 2)]
      self.balls += [Ball(p.x - 17, p.y + 10, gtk.gdk.Color(50887, 6939, 1285, 0), 3)]

      self.balls += [Ball(p.x - 34, p.y - 18, gtk.gdk.Color(32897, 0, 61681, 0), 4)]
      self.balls += [Ball(p.x - 34, p.y,      gtk.gdk.Color(0, 0, 0, 0), 8)]
      self.balls += [Ball(p.x - 34, p.y + 18, gtk.gdk.Color(58083, 135467, 0, 0), 5)]

      self.balls += [Ball(p.x - 51, p.y - 28, gtk.gdk.Color(3328, 38400, 3328), 6)]
      self.balls += [Ball(p.x - 51, p.y - 10, gtk.gdk.Color(29952, 11520, 8704), 7)]
      self.balls += [Ball(p.x - 51, p.y + 10, gtk.gdk.Color(63222, 53970, 2570, 0), 9)]
      self.balls += [Ball(p.x - 51, p.y + 28, gtk.gdk.Color(10280, 1542, 51658, 0), 10)]

      self.balls += [Ball(p.x - 68, p.y - 36, gtk.gdk.Color(50887, 6939, 1285, 0), 11)]
      self.balls += [Ball(p.x - 68, p.y - 18, gtk.gdk.Color(32897, 0, 61681, 0), 12)]
      self.balls += [Ball(p.x - 68, p.y,      gtk.gdk.Color(58083, 135467, 0, 0), 13)]
      self.balls += [Ball(p.x - 68, p.y + 18, gtk.gdk.Color(3328, 38400, 3328), 14)]
      self.balls += [Ball(p.x - 68, p.y + 36, gtk.gdk.Color(29952, 11520, 8704), 15)]

      # LUODAAN VALKOINEN PALLO
      self.balls += [Ball(495, p.y, gtk.gdk.Color(56320, 56320, 56320, 0), 0)]

      # LUODAAN PELAAJAT
      self.players = []
      self.players += [Player(1)]
      self.players += [Player(2)]

   def run( self ) :

      gtk.main()

   def restart_this_application( self, widget, data=None ) :
      if self.winner != 0 :
         self.callback_is_running = False
         self.callback = True

         if thread_in_use == True :
            self.thread_that_runs_the_game = ThreadThatRunsTheGame(self)
            self.thread_that_runs_the_game.start()

         else :
            gobject.timeout_add (30, self.callback_function) 
            
      self.start_game()

   def exit_this_application( self, widget, data=None ) :

      if thread_in_use == True :
         self.thread_that_runs_the_game.stop()
      else :
         self.callback = False

      gtk.main_quit()

   # ****************** PELIN PELAAMINEN ******************
   def play_game(self) :

      self.callback_is_running = True
      if self.change_player == True and self.ball_is_moving == False :

         dummy = self.player
         self.player = self.waiter
         self.waiter = dummy
         self.change_player = False


      one_ball_is_moving = False
      index = len(self.balls) - 1

      while index >= 0 :

         # LIIKUTETAAAN PALLOA
         if self.balls[index].move(self.table, self.balls) == True :

            one_ball_is_moving = True


         # JOS PALLO ON REIASSA
         if self.balls[index].ball_in_hole :

            if self.balls[index].radius > 4 :

               # PIENENNETAAN ENSIN PALLOA
               self.balls[index].set_radius(self.balls[index].radius - 0.5)

            else  :

               # VALKOINEN PALLO
               if self.balls[index].number == 0 :

                  # jos musta on pussitettu ja valkoinen menee reikaan
                  # niin vaihdetaan voittajaa
                  if self.winner != 0 :

                     self.winner = self.waiter

                  else  :

                     # LUODAAN UUSI PALLO
                     self.balls += [Ball(-100, -100, gtk.gdk.Color(56320, 56320, 56320, 0), 0)]

                     # UUDEN PALLON VOI ASETTAA POYDALLE HALUAMAANSA KOHTAAN
                     self.free_ball = True

                     # VAIHDETAAN PELAAJAA
                     self.change_player = True

                  self.is_shooted = False

               # KASI PALLO
               elif self.balls[index].number == 8 :

                  if self.players[self.player - 1].points == 7 :

                     self.winner = self.player

                  else  :

                     self.winner = self.waiter


                  self.is_shooted = False

               # MUUT PALLOT
               else  :

                  this_color = 0
                  not_this_color = 0
                  if self.balls[index].number < 8 :

                     this_color = 1
                     not_this_color = 2

                  else  :

                     this_color = 2
                     not_this_color = 1


                  # JOS PAKKA OLI TAYSI NIIN VALITAAN VARIT PELAAJILLE
                  if len(self.balls) == 16 :

                     self.players[self.player - 1].set_color(this_color)
                     self.players[self.waiter - 1].set_color(not_this_color)


                  if self.players[self.player - 1].color == this_color :

                     self.players[self.player - 1].add_point()

                  else  :

                     self.players[self.waiter - 1].add_point()
                     self.change_player = True


                  self.is_shooted = False


               # POISTETAAN PIENENNETTY PALLO
               self.balls.pop(index)
               index -= 1
         index -= 1

      # pallot liikkuu jos yksinkin pallo liikkuu
      self.ball_is_moving = one_ball_is_moving

      # JOS MIKAAN PALLO EI MENNYT REIKAAN NIIN VAIHDETAAN PELAAJAA
      if self.is_shooted == True and self.ball_is_moving == False :

         self.change_player = True
         self.is_shooted = False


      # ASETETAAN VOIMA TIKULLE
      # TARKISTETAAN ONKO LYOTY JA ASETETAAN VOIMA SEN MUKAAN
      if self.button_pressed_time != 0 and self.is_shooted == False :

         self.strength = int((time.time() - self.button_pressed_time) * 10)

         if self.strength > 25 :

            self.strength = 25

         self.stick.set_strength(self.strength)

      if self.must_shoot == True :

         self.is_shooted = self.stick.shoot(self.balls[len(self.balls) - 1])

         if self.is_shooted == True :
            # ASETETAAN LYONTIKOHTA
            self.balls[len(self.balls) - 1].set_sight_point(self.sight.get_sight_point())
            self.must_shoot = False

      self.drawing_area.queue_draw()
      self.callback_is_running = False

   # ########### HIIRI JUTUT ############### #

   def mouse_button_pressed( self, widget, event ) :

      self.mouse_x = int( event.x )
      self.mouse_y = int( event.y )

      if self.sight.contains_point(Point(self.mouse_x, self.mouse_y)) :

         self.sight_is_changed = True
         self.sight.set_sight_point(Point(self.mouse_x, self.mouse_y))

      elif self.must_shoot == False and self.is_shooted == False and \
           self.ball_is_moving == False and self.free_ball == False and \
           self.first_time_free_ball == False :

         self.stick.moveStick(Point(self.mouse_x, self.mouse_y),
                              self.balls[len(self.balls) - 1])

         self.button_pressed_time = time.time()

   def mouse_motion_notified( self, widget, event ) :

      self.mouse_x, self.mouse_y, state = event.window.get_pointer()

      if self.is_shooted == False and self.ball_is_moving == False :

         # KA:SIPALLON ASETUS
         if self.free_ball == True and self.change_player == False :

            self.balls[len(self.balls) - 1].move_to(Point(self.mouse_x,
                                                    self.mouse_y))

         elif self.first_time_free_ball == True and \
              self.mouse_y >= 80 and self.mouse_y <= 340 :

            self.balls[len(self.balls) - 1].move_to(Point(495, int(self.mouse_y)))

         self.stick.moveStick(Point(self.mouse_x, self.mouse_y),
                              self.balls[len(self.balls) - 1])

   def mouse_button_released( self, widget, event ) :

      if  event.button  ==  1  :
         if self.free_ball == True or \
            self.first_time_free_ball == True  and \
            self.sight_is_changed == False :

            self.free_ball = False
            self.first_time_free_ball = False

         elif self.is_shooted == False and \
              self.ball_is_moving == False and \
              self.sight_is_changed == False :

            # AMMUTAAN
            self.must_shoot = True

         self.button_pressed_time = 0
         self.sight_is_changed = False

   def drawing_area_exposed( self, area, event ) :

      graphics_context  =  self.drawing_area.get_style().fg_gc[gtk.STATE_NORMAL]
      this_drawable  =  self.drawing_area.window

      # PIIRRETAAN POYTA
      self.table.draw(self.drawing_area)

      # PIIRRETAAN PALLOT
      for i in range(len(self.balls)) :
         self.balls[i].draw(self.drawing_area)

      # PIIRRETAAN TIKKU JA TAHTAIN JOS YKSIKAAN PALLO EI LIIKU
      if self.free_ball == False and self.ball_is_moving == False :
         self.stick.draw(self.drawing_area, self.balls[len(self.balls) - 1])


      # PIIRRETAAN TAHTAIN
      self.sight.draw(self.drawing_area)

      graphics_context.set_rgb_fg_color(gtk.gdk.Color(0, 0, 0, 0))
      text_to_show   =  self.drawing_area.create_pango_layout("")
      text_to_show.set_font_description(pango.FontDescription( "arial 9" ))

      text_to_show.set_text("Player %d" % self.players[self.player - 1].player_number)
      this_drawable.draw_layout( graphics_context, 20, 0, text_to_show)

      text_to_show.set_text("Points %d" % self.players[self.player - 1].points)
      this_drawable.draw_layout( graphics_context, 20, 15, text_to_show)

      text_to_show.set_text("Color %s" % self.players[self.player - 1].get_color_with_string())
      this_drawable.draw_layout( graphics_context, 100, 0, text_to_show)

      text_to_show.set_text("Strength %d" % self.strength)
      this_drawable.draw_layout( graphics_context, 100, 15, text_to_show)
 
      text_to_show.set_text("Radian %f" % self.stick.radian)
      this_drawable.draw_layout( graphics_context, 180, 0, text_to_show)



      # TAHTAIMEN KOORDINAATIT
      text_to_show.set_text("X : %d" % self.sight.sight_x)
      this_drawable.draw_layout( graphics_context, 620, 0, text_to_show)

      text_to_show.set_text("Y : %d" % self.sight.sight_y)
      this_drawable.draw_layout( graphics_context, 620, 15, text_to_show)

      if self.winner != 0 and self.ball_is_moving == False :

         text_to_show.set_font_description(pango.FontDescription( "arial 30" ))
         text_to_show.set_text("PLAYER %d WON!" % self.players[self.winner - 1].player_number)
         this_drawable.draw_layout( graphics_context, 200, 200, text_to_show)
         if thread_in_use == True :
            self.thread_that_runs_the_game.stop()
         else :
            self.callback = False

      return True

#main
this_application  =  Pool()
this_application.run()



