By _dave_ at 2+2 forums.

The corresponding thread on 2+2 is here. The thread on the 'new' forums is here.

Stars Planner

I consider PartyPlanner one of the most useful helper apps available for play on Party / Empire, but unfortunately it does not function for Poker Stars yet. When it does, this script will be obselete, I should imagine.

This script mimics the automatic table resizing and positioning found in PartyPlanner, but for Poker Stars.

You can set desired table size, and location on screen - new tables will be moved to pre-defined slots automatically.

Once tables are open, they may be dragged to another "slot", swapping with the table already there if there is one (like PartyPlanner)

Also let me know if you are having trouble - there may well be errors and/or bugs. I won't find them all on my own :) Also let me know if you like and use the script - it is always nice to recieve good feedback.

Give it a try, see what you think.

Hopefully people will find this useful, I certainly do.

Enjoy,

dave.

Screenshot

http://img299.imageshack.us/img299/4613/starsplannerv003td0.png

Download

StarsPlanner-v0.4g.ahk

If you want to download any older versions for any reasonn - hit attachments at the top of this page

Instructions

LIMIT PLAYERS - do not use the "Automatic Buy-In" option - unless you want to bring your whole roll to the table. This will be configurable in the next version.

Enjoy!

Revision History

v0.01 (Testing)

Initial release.

v0.02

Fixed a problem with pixel co-ordinates, whereby tables would be swapped when there was no need to do so

Added some pop-up busting - "Welcome to Tournament..." etc pop-ups would prevent resizing of tables, causing a lock.

v0.03

Big update, lots of changes / new features.

Made a little GUI to control behaviour / switch layouts / toggle on/off various features

Added ability to "Capture" a layout from presently open Stars tables

Added a layout configuration function to change the order in which slots are populated.

Added some more popups to the popup buster list

Figured out how to use ini files to preserve settings between uses.

v0.03a

Bugfix release - Fixed a couple of bugs in the "Table Capture" / "Layout Manager" sections - oops :)

v0.03b

Minor update - added a few more dialog boxes to the popup buster section - think I got most of them now. More importantly, some of the "Waiting List" pop-ups were causing a lock situation, similar to the "Welcome to Tournament" pop-up lock discovered in earlier versions. This is now fixed :)

v0.03c

Tiny update - Altered it slightly so that it also recognises and plans resized Full Tilt tables, as created by ResizeableTables - you can mix and match Stars and (Resized FT tables now :)

v0.03d

Minor update for compatibility fixes with StarsSNGOpener script.

v0.04

Update to fix compatibility with Stars new dialog boxes. Also improved resize code thanks to Crashpat on 2p2 SW Forum.

IMPORTANT NOTES: to make use of superior window-resize method, you have to add the line "f5redrawtable=1" (without quotes) to the [Options] section in your "User.ini" file - found in "Program Files\PokerStars". I could have the script do this automatically, but I'd rather not be writing to PokerStars files if I can help it.

With the version number change, you will need to copy/paste your StarsPlanner-v0.03.ini file and rename it to StarsPlanner-v0.04.ini - This will preserve previously saved table layouts.

I enhanced the behaviour of the "Dismiss Open-Fold Are You Sure" setting. Now when unticked, it will auto Check :)

I added a menu option (right click the tray "H" icon) to Reset GUI position - never happened to me, but some people reported an off-screen GUI window. This option moves it to x/y 0,0 - should be visible on any system.

v0.4b

Added remembering of lobby position for "Keep Lobby up" setting Implemented faster more reliable pop-up killing for those pesky new-style Stars dialogs.

v0.4c

Added planning of Full Tilt and Party Poker tables. No pop-up handling or any other conviniences for these sites - use FullTiltPlanner and/or PartyAHKPlanner for such purposes. DO NOT HAVE PLANNING ENABLED FOR MORE THAN ONE OF THESE APPS OR THEY WILL FIGHT EACH OTHER FOR THE TABLES!!! set variables "arrange_party_empire := 0" and/or "arrange_full_tilt := 0" to stop StarsPlanner finding these tables if so desired.

Added an "Emergency Stop" hotkey (CTRL+F12) or kill switch (CTRL+ALT+F12) in case a corrupted layout file causes excessive table swapping.

v0.4d (14-Sep-2007)

Added planning of Absolute Poker tables since their new client is now resizeable (basic, more to come surely... rushed release because of urgency due to below)

Fixed crippling focus-stealing issues on PokerStars introduced by today's update.

v0.4f (29-Apr-2008)

Added handling of waiting list pop-ups

Added separate checkbox for "untick auto post"

Added no-taskbar-icon mode

Made usef5redraw default, with warning.

v0.4g (31-May-2008)

Made the Stars waitlist handling a little nicer, added option to turn off "auto-answer" mode

Added OnGame, iPoker, Crypto and Prima layout function (still PokerStars tables only for capture mode)

Added option to insta-leave tables on Stars

Added option to minimize Stars lobby when all slots are full

Fixed an error or two hopefully :)

Code

;------------------------------------------------------------------------------------------
;;;;;;;;;;;;;;;;; CODE STARTS HERE

/*
Stars Planner, by _dave_ at 2+2 forums
Contributions by Roland, Jukofyork, CrashPat, I'm sure others also.


Mimics some of the layout behaviour of the fantastic PartyPlanner,
but for PokerStars table windows. Enjoy!

*/

arrange_party_empire := 1
arrange_full_tilt := 1
arrange_absolute := 1
arrange_crypto := 1
arrange_prima := 1
arrange_ipoker := 1
arrange_ongame := 1


kill_leave_table := 0
minimize_lobby_when_full := 1
answer_waitlists := 1
minimize_to_tray := 1

ignore_min := 0
ignore_left_pos := 0


do_not_use_f5redraw := 0

#NoEnv 
#SingleInstance, Force
SendMode Input

using_sngopener := 1

SysGet, border, 32
SysGet, caption, 4

;----------- IMPORTANT -------------;
;
;  Add the following line:
;
;  f5redrawtable=1
;
;  to the [Options] section in your
;  PokerStars "User.ini" file, found
;  in "Program Files\PokerStars"
;
;  The below few lines check for this
;  setting, so we can use it if it is
;  available.
;
;  Increases performance greatly :) 
;
;-----------------------------------;

path := A_ProgramFiles . "\PokerStars\User.ini"
IniRead, f5redrawtable, %path%, Options, f5redrawtable, 1
;MsgBox, %f5redrawtable%
if (!f5redrawtable)
{
  Msgbox, Unable to read f5redrawtable setting in user.ini.`n`n Please add "f5redrawtable=1" in the [options] section of PokerStars "user.ini" `nor cash games will not resize properly!
}
Menu, Tray, Add,Reset GUI Position, ResetGUI
Menu, Tray, Add,Restore GUI, RestoreGUI
;Menu, Tray, Default,Reset GUI Position
if (do_not_use_f5redraw)
{
  f5redrawtable := 0
}
mouse_position_swap_method := 1

slotcount := 0
w := 5
h := 6
x := 3
y := 345
Loop, 24
{
  Loop, 2
  {
    slotcount += 1
    slot%slotcount%w := w
    slot%slotcount%h := h
    slot%slotcount%x := x
    slot%slotcount%y := y
    slot%slotcount%id := ""
  }
}
slotcount := 24

customfillorder = 1,2,3,4

SetTimer, DoPlanning, 250
SetTimer, DoPlanning, Off

SetTimer, DoPlanningConfig, 250
SetTimer, DoPlanningConfig, Off


SetTimer, KillPopUps, 200
SetTimer, KillPopUps, Off

SetTimer, KeepLobbyUp, 1000
SetTimer, KeepLobbyUp, Off

inifile := "StarsPlanner-v0.04.ini"
ChosenLayout := 0
AutoBuyInOn := 0
KillFoldConfirmOn := 0
FileGetSize, inipresent, %inifile%
if (ErrorLevel)
{
  str := "[Layouts]`nnumlayouts=0`n`n[Defaults]`nPlanTablesOn=0`nKeepLobbyOn=0`nAutoBuyInOn=0`nKillFoldConfirmOn=0`nChosenLayout=0`ngx=0`ngy=0"
  FileAppend, %str%, %inifile%
}

Gui, Add, Checkbox, vPlanTables gPlanTables x10 y10, Enable Re-Size and Arrange Tables
Gui, Add, Checkbox, vKeepLobby gKeepLobby x10 y30, Enable Keep Lobby
Gui, Add, Checkbox, vAutoBuyIn gAutoBuyIn x10 y50, Enable Automatic Buy In when seated
Gui, Add, Checkbox, vKillFoldConfirm gKillFoldConfirm x10 y70, Dismiss Open-fold "Are you sure?"
Gui, Add, Checkbox, vSitInOut gSitInOut x240 y10, Sit Out on all tables (untick to return)
Gui, Add, Checkbox, vHitAutoPost gHitAutoPost x240 y30, Check/Uncheck Auto Post
Gui, Add, ComboBox, vLayoutChoice gLayoutChoice w190 x240 y50 Limit AltSubmit
Gui, Add, Button, vCaptureLayout gCaptureLayout x240 y80 w60 h30 , Capture
Gui, Add, Button, vConfigureLayout gConfigureLayout x305 y80 w60 h30 , Configure
Gui, Add, Button, vDeleteLayout gDeleteLayout x370 y80 w60 h30 , Delete
Gui, Add, Button, Hidden vConfigSave gConfigSave x240 y80 w90 h30 , Save Layout
Gui, Add, Button, Hidden vConfigCancel gConfigCancel x340 y80 w90 h30 , Cancel

if (minimize_to_tray)
{
  Gui, +ToolWindow
}

IniRead, gx, %inifile%, Defaults, gx
IniRead, gy, %inifile%, Defaults, gy

IniRead, lobbyx, %inifile%, Defaults, lobbyx
IniRead, lobbyy, %inifile%, Defaults, lobbyy


Gui, Show, x%gx% y%gy% h120 w440, Stars Planner v0.4g ( by _dave_ )
IniRead, ChosenLayout, %inifile%, Defaults, ChosenLayout
refresh_layout()

IniRead, PlanTablesOn, %inifile%, Defaults, PlanTablesOn
if (PlanTablesOn)
{
  GuiControl, , PlanTables, %PlanTablesOn%
  GoSub PlanTables
}

IniRead, KeepLobbyOn, %inifile%, Defaults, KeepLobbyOn
if (KeepLobbyOn)
{
  GuiControl, , KeepLobby, %KeepLobbyOn%
  SetTimer, KeepLobbyUp, On
  ;GoSub KeepLobby
}

IniRead, AutoBuyInOn, %inifile%, Defaults, AutoBuyInOn
if (AutoBuyInOn)
{
  GuiControl, , AutoBuyIn, %AutoBuyInOn%
  GoSub AutoBuyIn
}

IniRead, KillFoldConfirmOn, %inifile%, Defaults, KillFoldConfirmOn
if (AutoBuyInOn)
{
  GuiControl, , KillFoldConfirm, %KillFoldConfirmOn%
  GoSub KillFoldConfirm
}

GroupAdd, PartyTables, Good Luck ahk_class #32770,,, : Poker Lobby
GroupAdd, FullTiltTables, ahk_class FTC_TableViewFull
GroupAdd, AbsoluteTables, Players - Good Luck ahk_class DxWndClass
GroupAdd, PrimaTables, ahk_class POPUP_INT_DLG_WINDOW
GroupAdd, ipokerTables,$ ahk_class PTIODEVICE,,, : Nickname:
GroupAdd, ongametables,$ ahk_class AfxFrameOrView70u,,, - Welcome



SetTimer, KillPopUps, On
return

^!F12::
Suspend
return

^!q::
ExitApp
return

^f12::
  GuiControl, , PlanTables, 0
  GoSub PlanTables
return

ResetGUI:
gx=0
gy=0
Gui, Show, x%gx% y%gy% h120 w440, Stars Planner v0.4g ( by _dave_ )
return

RestoreGUI:
Gui, Show, , Stars Planner v0.4g ( by _dave_ )
return

GUIClose:
  Gui, Submit, NoHide
  IniDelete, %inifile%, Defaults
  IniWrite, %PlanTables%, %inifile%, Defaults, PlanTablesOn
  IniWrite, %KeepLobby%, %inifile%, Defaults, KeepLobbyOn
  IniWrite, %AutoBuyIn%, %inifile%, Defaults, AutoBuyInOn
  IniWrite, %KillFoldConfirm%, %inifile%, Defaults, KillFoldConfirmOn
  IniWrite, %ChosenLayout%, %inifile%, Defaults, ChosenLayout
  WinGetPos, gx, gy, , , Stars Planner v0.4
  IniWrite, %gx%, %inifile%, Defaults, gx
  IniWrite, %gy%, %inifile%, Defaults, gy
  
  WinGet, id, id, PokerStars Lobby
  WinGetPos, lx, ly, , , ahk_id%id%
  IniWrite, %lx%, %inifile%, Defaults, lobbyx
  IniWrite, %ly%, %inifile%, Defaults, lobbyy
  GUI, Cancel
  ;ExitApp
return

PlanTables:
Gui, Submit, NoHide
if (PlanTables)
{
  GuiControl, Disable, CaptureLayout 
  GuiControl, Disable, ConfigureLayout
  GuiControl, Disable, DeleteLayout
  SetTimer, DoPlanning, On
}
else
{
  SetTimer, DoPlanning, Off
  GuiControl, Enable, CaptureLayout 
  GuiControl, Enable, DeleteLayout
  GuiControl, Enable, ConfigureLayout
}
return

KeepLobby:
Gui, Submit, NoHide
if (KeepLobby)
{
  WinGet, id, id, PokerStars Lobby
  WinGet, ismin, MinMax, ahk_id%id%  
  If (ismin = -1)
  {
    WinRestore, ahk_id%id%
  }
  WinGet, id, id, PokerStars Lobby
  WinGetPos, lobbyx, lobbyy, , , ahk_id%id%
  SetTimer, KeepLobbyUp, On
}
else
{
  SetTimer, KeepLobbyUp, Off
}
return

AutoBuyIn:
Gui, Submit, NoHide
if (AutoBuyIn)
{
  AutoBuyInOn := 1
}
else
{
  AutoBuyInOn := 0
}
return

KillFoldConfirm:
Gui, Submit, NoHide
if (KillFoldConfirm)
{
  KillFoldConfirmOn := 1
}
else
{
  KillFoldConfirmOn := 0
}
return

SitInOut:
Gui, Submit, NoHide
SetTitleMatchMode, 2
x := 12
y := 377
;y := 398

WinGet, id, id, PokerStars Lobby
WinGet, ps_pid, PID, ahk_id%id%  
WinGet, list, list, Logged In as ahk_pid%ps_pid%, ,PokerStars Lobby
Loop, %list%
{
  id := list%A_Index%
  ;WinActivate, ahk_id%id%
  PostStarsClick(x, y, id)
}
return

HitAutoPost:
Gui, Submit, NoHide
SetTitleMatchMode, 2
x := 12
y := 377
y := 398

WinGet, id, id, PokerStars Lobby
WinGet, ps_pid, PID, ahk_id%id%  
WinGet, list, list, Logged In as ahk_pid%ps_pid%, ,PokerStars Lobby
Loop, %list%
{
  id := list%A_Index%
  ;WinActivate, ahk_id%id%
  PostStarsClick(x, y, id)
}
return

LayoutChoice:
Gui, Submit, NoHide
ChosenLayout := LayoutChoice
refresh_layout()
return

DeleteLayout:
Gui, Submit, NoHide
Gui +OwnDialogs
IniRead, layoutname, %inifile%, Layouts, %LayoutChoice%

Msgbox, 4 , , You are about to delete the saved layout:`n`n%layoutname%`n`nAre You Sure?
IfMsgBox, Yes
{
  Critical
  IniRead, numlayouts, %inifile%, Layouts, numlayouts
  FileRead, file, %inifile%
  
  if not ErrorLevel
  {
    IniDelete, %inifile%, Layouts, %LayoutChoice%
    IniDelete, %inifile%, Layout%LayoutChoice%
    newnumlayouts := numlayouts - 1
    IniWrite, %newnumlayouts%, %inifile%, Layouts, numlayouts
    FileRead, file, %inifile%
    
    c := numlayouts - LayoutChoice
    needchanged := ""
    Loop, %c%
    {
      n := (numlayouts - A_Index) + 1
      needchanged := n . "," . needchanged
    }
    StringTrimRight, needchanged, needchanged, 1
    Loop, Parse, needchanged, `,
    {
      oldnum := "`n" . A_LoopField . "="""
      newnum := "`n" . (A_LoopField - 1) . "="""
      StringReplace, file, file, %oldnum%, %newnum%, A
      
      oldstr := "[Layout" . A_LoopField . "]"
      newstr := "[Layout" . (A_LoopField - 1) . "]"
      StringReplace, file, file, %oldstr%, %newstr%, A
      
    }
    FileDelete, %inifile%
    FileAppend, %file%, %inifile%
  }
  Critical, Off
  IniRead, numlayouts, %inifile%, Layouts, numlayouts
  if (ChosenLayout > numlayouts)
  {
    ChosenLayout -= 1
    ChosenLayout := IIf(ChosenLayout, ChosenLayout, 0)
    IniWrite, %ChosenLayout%, %inifile%, Defaults, %ChosenLayout%
  }
  refresh_layout()
}
return


CaptureLayout:
Gui +OwnDialogs
InputBox, newlayout, Layout Name, Please enter a name for this captured layout., , , , gx+10, gy+30, , ,
if (!ErrorLevel)
{
  tl := ""
  tl2 := ""
  if (newlayout = "")
  {
    Msgbox, Please enter a name for the new layout
    return
  }
  tables := TableIDListStars()
  numtables := 0
  Loop, Parse, tables, `,
  {
    numtables += 1
  }
  t := 0
  tl := ""
  if (numtables > 0)
  {
    Loop, Parse, tables, `,
    {
      t += 1
      WinGetPos, l%t%x, l%t%y, l%t%w, l%t%h, ahk_id%A_LoopField%
      tl := tl . "," . t
    }
    StringTrimLeft, tl, tl, 1
    
    Msgbox, Found %t% PokerStars tables
    order := ""
    if (t > 0)
    {
      Loop, %t%
      {
        order := order . "," . l%A_Index%x . "." . l%A_Index%y
      }
      StringTrimLeft, order, order, 1
      Sort, order, N D,
      
      Loop
      {
        Loop, Parse, order, `,
        {
          
          StringTrimRight, x, A_LoopField, (StrLen(A_LoopField) - InStr(A_LoopField, "."))+1
          StringTrimLeft, y, A_LoopField, InStr(A_LoopField, ".")
          Loop, Parse, tl, `,
          {
            if (l%A_LoopField%x = x && l%A_LoopField%y = y)
            {
              tmp := A_LoopField
              tl := RemoveFromList(tl,tmp)
              tl2 := tl2 . "," . tmp
              break
            }
          }
        }
        if (tl = "")
        {
          break
        }
      }
      StringTrimLeft, tl2, tl2, 1
      sect := numlayouts + 1
      cl := ""
      Loop, Parse, tl2, `,
      {
        x := l%a_loopfield%x
        y := l%a_loopfield%y
        w := l%a_loopfield%w
        h := l%a_loopfield%h
        IniWrite, %x%, %inifile%, Layout%sect%, %A_Index%x
        IniWrite, %y%, %inifile%, Layout%sect%, %A_Index%y
        IniWrite, %w%, %inifile%, Layout%sect%, %A_Index%w
        IniWrite, %h%, %inifile%, Layout%sect%, %A_Index%h
        cl := cl . "," . A_Index
      }
      StringTrimLeft, cl, cl, 1
      
      IniDelete, %inifile%, Layouts, numlayouts
      IniWrite, %sect%, %inifile%, Layouts, numlayouts
      IniWrite, "%newlayout%", %inifile%, Layouts, %sect%
      IniWrite, %t%, %inifile%, Layout%sect%, slotcount
      IniWrite, %cl%, %inifile%, Layout%sect%, customfillorder
      ChosenLayout := sect
      refresh_layout()
    }
  }
}
return

ConfigureLayout:
Gui, Submit, NoHide
ChosenLayout := LayoutChoice
GuiControl, Disable, PlanTables
GuiControl, Disable, LayoutChoice
GuiControl, Hide, CaptureLayout
GuiControl, Hide, ConfigureLayout
GuiControl, Hide, DeleteLayout

filename := "StarsPlannerConfigureLayoutGUI.ahk"
FileDelete, %filename%

guinum := 10
Loop, %slotcount%
{
  x := slot%A_Index%x
  y := slot%A_Index%y
  w := slot%A_Index%w
  h := slot%A_Index%h
  w := w - (2*border)
  h := h - (2*border) - caption
  guinum += 1
  str := "Gui " . guinum . ": -Resize -SysMenu`n"
  FileAppend, %str%, %filename%
  str := "Gui " . guinum . ": Font, c0000ff s40 bold, Arial`n"
  FileAppend, %str%, %filename%
  str := "Gui " . guinum . ": Add, Text, , Slot " . A_Index . "`n"
  FileAppend, %str%, %filename%
  str := "Gui " . guinum . ": Show , w" . w . " h" . h . " x" . x . " y" . y . " , Stars Planner Slot #" . A_Index . "`n"
  FileAppend, %str%, %filename%
  

}
Run "AutoHotkey.exe" "/f" "%filename%"
SetTitleMatchMode, 3
Loop, %slotcount%
{
  WinWait, Stars Planner Slot #%A_Index%
  WinGet, id, id, Stars Planner Slot #%A_Index%
  s := ExFromList(customfillorder,A_Index)
  slot%s%id := id
}
SetTimer, DoPlanningConfig, On
Sleep, 2000
GuiControl, Show, ConfigSave
GuiControl, Show, ConfigCancel

FileDelete, %filename%
  

return

ConfigSave:
  filename := "StarsPlannerConfigureLayoutGUI.ahk"
  GuiControl, Hide, ConfigSave
  GuiControl, Hide, ConfigCancel
  GuiControl, Show, CaptureLayout
  GuiControl, Show, ConfigureLayout
  GuiControl, Show, DeleteLayout
  
  order := ""
  SetTitleMatchMode 3
  Loop, %slotcount%
  {
    title := "Stars Planner Slot #" . A_Index
    WinGet, id, id, %title%
    s := 0
    Loop, %slotcount%
    {
      s += 1
      if (slot%s%id = id)
      {
        order := order . "," . s
        break
      }
    }
  }
  
  StringTrimLeft, order, order, 1
  SetTitleMatchMode 2
  DetectHiddenWindows, On
  WinGet, list, list, %filename%
  Loop, %list%
  {
    id := list%A_Index%
    WinClose, ahk_id%id%
  }
  DetectHiddenWindows, Off
  SetTimer, DoPlanningConfig, Off
  
  IniDelete, %inifile%, Layout%ChosenLayout%, customlayout
  IniWrite, %order%, %inifile%, Layout%ChosenLayout%, customfillorder
  GuiControl, Enable, LayoutChoice
  GuiControl, Enable, PlanTables
  refresh_layout()

  
return

ConfigCancel:
  GuiControl, Hide, ConfigSave
  GuiControl, Hide, ConfigCancel
  GuiControl, Show, CaptureLayout
  GuiControl, Show, ConfigureLayout
  GuiControl, Show, DeleteLayout
  SetTitleMatchMode 2
  DetectHiddenWindows, On
  WinGet, list, list, %filename%
  Loop, %list%
  {
    id := list%A_Index%
    WinClose, ahk_id%id%
  }
  DetectHiddenWindows, Off
  SetTimer, DoPlanningConfig, Off
  GuiControl, Enable, LayoutChoice
  GuiControl, Enable, PlanTables
  
return



refresh_layout()
{
  global
  SetTimer, DoPlanning, Off
  IniRead, numlayouts, %inifile%, Layouts, numLayouts
  layoutlist := ""
  Loop, %numLayouts%
  {
    IniRead, tmp, %inifile%, Layouts, %A_Index%
    layoutlist := layoutlist . tmp
    if (A_Index < numlayouts)
    {
      layoutlist := layoutlist . "|"
    }
  }
  GuiControl,, LayoutChoice, |%layoutlist%
  GuiControl, Choose, LayoutChoice, %ChosenLayout%
  
  IniRead, slotcount, %inifile%, Layout%ChosenLayout%, slotcount
  Loop, %slotcount%
  {
    IniRead, slot%A_Index%x, %inifile%, Layout%ChosenLayout%, %A_Index%x
    IniRead, slot%A_Index%y, %inifile%, Layout%ChosenLayout%, %A_Index%y
    IniRead, slot%A_Index%w, %inifile%, Layout%ChosenLayout%, %A_Index%w
    IniRead, slot%A_Index%h, %inifile%, Layout%ChosenLayout%, %A_Index%h
    slot%A_Index%id := ""
  }
  IniRead, customfillorder, %inifile%, Layout%ChosenLayout%, customfillorder
  
  if (PlanTables)
  {
    SetTimer, DoPlanning, On
  }

}


reverse_calc_stars_client_area(cw, ByRef w, ByRef h)
{
  global border
  global caption
  w := cw + (2*border) 
  h := Floor(cw / 1.45) + (2*border) + caption
}


/*
win_adjustsize(id, desired_w)
{
  global border
  global caption
  WinGetClass, winclass, ahk_id%id%
  ;Msgbox, %winclass%
  if (winclass = "AutoHotkeyGUI")
  {
    ;Msgbox, AHKwin
    desired_h := (desired_w / 1.45155) + border + caption
    WinMove, ahk_id%id%, , , , desired_w, desired_h
    
  }
  else
  {
    WinGetPos, x, y, w, h, ahk_id%id%
    x1 := x + w-1
    y1 := y + h-1
    amt := desired_w - w
    WinActivate,ahk_id%id%
    BlockInput, SendAndMouse
    MouseGetPos, x, y
    MouseMove, %x1%, %y1%, 0
    Click, %x1%, %y1%, D
    MouseMove, amt, 0, 0, R
    Click, U
    MouseMove, x, y, 0
    BlockInput, Default
  }
}
*/
win_adjustsize(id, desired_w)
{
  global border
  global caption
  global f5redrawtable

  WinGetClass, winclass, ahk_id%id%
  ;Msgbox, %winclass%
  IfWinExist, ahk_id%id% ahk_group FullTiltTables
  {
    desired_h := (desired_w / 1.45155) + border + caption
    WinMove, ahk_id%id%, , , , desired_w, desired_h
  }
  else IfWinExist, ahk_id%id% ahk_group PartyTables
  {
    desired_h := (desired_w / 1.45155) + border + caption
    WinMove, ahk_id%id%, , , , desired_w, desired_h
  }
  else IfWinExist, ahk_id%id% ahk_group AbsoluteTables
  {
    desired_h := (desired_w / 1.45155) + border + caption
    WinMove, ahk_id%id%, , , , desired_w, desired_h
  }
  else if (winclass = "AutoHotkeyGUI")
  {
    ;Msgbox, AHKwin
    desired_h := (desired_w / 1.45155) + border + caption
    WinMove, ahk_id%id%, , , , desired_w, desired_h
    
  }
  else IfWinExist, ahk_id%id% ahk_group CryptoTables
  {
    ; ignore, can't resize
  }
  else IfWinExist, ahk_id%id% ahk_group ongameTables
  {
    ; ignore, can't resize
  }
  else IfWinExist, ahk_id%id% ahk_group PrimaTables
  {
    ; ignore, can't resize
  }
  else IfWinExist, ahk_id%id% ahk_group ipokerTables
  {
    ; ignore, can't resize
  }
  else
  {
    WinGetTitle, title, ahk_id%id%
    tourney := InStr(title, "Tournament")
    if (f5redrawtable && (tourney < 1))
    {
      ;Msgbox, in
      desired_h := (desired_w / 1.45155) + border + caption
      WinMove, ahk_id%id%, , , , desired_w, desired_h
      Sleep, -1
      ControlSend, , {F5}, ahk_id%id%
    }
    else
    {
      WinMove, ahk_id%id%, , 0, 0
      WinGetPos, x, y, w, h, ahk_id%id%
      x1 := x + w-4
      y1 := y + h-4
      amt := desired_w - w
      WinActivate,ahk_id%id%
      BlockInput, SendAndMouse
      MouseGetPos, x, y
      MouseMove, %x1%, %y1%, 0
      Click, %x1%, %y1%, D
      MouseMove, amt, 0, 0, R
      Click, U
      MouseMove, x, y, 0
      BlockInput, Default
    }
  }
}



TableIDListStars()
{
  SetTitleMatchMode 2
  WinGet, id, id, PokerStars Lobby
  WinGet, pid, PID, ahk_id%id%
  WinGet, list, list, $ ahk_pid%pid%
  Loop %list%
  {
    this_id := list%a_index%
    If (this_id != id)
    {
      ids = %ids%,%this_id%
    }
  }
  
  StringTrimLeft, ids, ids, 1
  return ids
}

TableIDListAll()
{
  global arrange_party_empire
  global arrange_full_tilt
  global arrange_absolute
  global arrange_crypto
  global arrange_prima
  global arrange_ipoker
  global arrange_ongame
  global ignore_min, ignore_left_pos

  SetTitleMatchMode 2
  WinGet, id, id, PokerStars Lobby
  WinGet, pid, PID, ahk_id%id%
  WinGet, list, list, $ ahk_pid%pid%
  Loop %list%
  {
    this_id := list%a_index%
    If (this_id != id)
    {
      if (ignore_min)
      {
        WinGet, ismin_t, MinMax, ahk_id%this_id%
        if (ismin_t = -1)
        {
          ;Msgbox, dsadasd
          continue
        }
      }
      if (ignore_left_pos)
      {
        WinGetPos, x_t, , , , ahk_id%this_id%
        if (x_t < ignore_left_pos)
        {
          ;Msgbox, dsadasd
          continue
        }
      }
      ids = %ids%,%this_id%
    }
  }
  WinGet, list, list, MiniFT ahk_class AutoHotkeyGUI
  Loop %list%
  {
    this_id := list%a_index%
    ids = %ids%,%this_id% 
  }
  
  if(arrange_full_tilt)
  {
    WinGet, list, list, ahk_class FTC_TableViewFull
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%  
    }
  }
    
  if (arrange_party_empire)
  {
    WinGet, list, list, Good Luck ahk_class #32770, ,: Poker Lobby
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%
    }
  }
  
  if (arrange_absolute)
  {
    WinGet, list, list, Players - Good Luck ahk_class DxWndClass
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%
    }
  }
  
  if (arrange_crypto)
  {
    WinGet, sunpoker, pid,  SunPoker.com - Lobby
    WinGet, interpoker, pid,  InterPoker - Lobby
    WinGet, willhill, pid,  William Hill Poker - Lobby
    WinGet, betsafe, pid, Betsafe Poker - Lobby
    WinGet, parbet, pid, Parbet.com Poker - Lobby
    WinGet, lw, pid, Littlewoods Poker - Lobby
    WinGet, dtd, pid, DTD Poker - Lobby
    
    if (sunpoker)
    {
      GroupAdd, CryptoTables,Logged in as ahk_pid%sunpoker%,,, Lobby
    }
    WinGet, list, list, Logged in as ahk_pid%sunpoker%,, Lobby
    ;Msgbox, %list%
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%
    }
    
    WinGet, list, list, Logged in as ahk_pid%interpoker%,, Lobby
    if (interpoker)
    {
      GroupAdd, CryptoTables, ahk_pid%interpoker%,,, Lobby
    }
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%
    }
    
    
    WinGet, list, list, Logged in as ahk_pid%willhill%,, Lobby
    if (willhill)
    {
      GroupAdd, CryptoTables, ahk_pid%willhill%,,, Lobby
    }
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%
    }
    
    WinGet, list, list, Logged in as ahk_pid%betsafe%,, Lobby
    if (betsafe)
    {
      GroupAdd, CryptoTables, ahk_pid%betsafe%,,, Lobby
    }
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%
    }
    
    WinGet, list, list, Logged in as ahk_pid%parbet%,, Lobby
    if (parbet)
    {
      GroupAdd, CryptoTables, ahk_pid%parbet%,,, Lobby
    }
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%
    }
    
    WinGet, list, list, Logged in as ahk_pid%lw%,, Lobby
    if (lw)
    {
      GroupAdd, CryptoTables, ahk_pid%lw%,,, Lobby
    }
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%
    }
    
    WinGet, list, list, Logged in as ahk_pid%dtd%,, Lobby
    if (dtd)
    {
      GroupAdd, CryptoTables, ahk_pid%dtd%,,, Lobby
    }
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%
    }
    
  }
  
  if (arrange_prima)
  {
    WinGet, list, list, ahk_class POPUP_INT_DLG_WINDOW
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%
    }
  }

  if (arrange_ipoker)
  {
    ;msgbox, xxx
    WinGet, list, list,$ ahk_class PTIODEVICE,, : Nickname:
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%
    }
  }
  
  if (arrange_ongame)
  {
    ;msgbox, xxx
    WinGet, list, list,$ ahk_class AfxFrameOrView70u,, - Welcome
    Loop %list%
    {
      this_id := list%a_index%
      ids = %ids%,%this_id%
    }
  }
  
  StringTrimLeft, ids, ids, 1
  return ids
}



fixtables()
{
  global slotcount
  global customfillorder
  global mouse_position_swap_method
  global border
  global caption
  
  tables := TableIDListAll()
  t := ""
  
  
  GetKeyState, state, LButton
  if (state = "D")
  {
    MouseGetPos, , , id
    if (InStr(tables, id))
    {
      Sleep, 70
      GetKeyState, state, LButton
      if (state = "D")
      {
        Loop
        {
          Sleep, 10
          GetKeyState, state, LButton
          if (state = "U")
          {
            MouseGetPos, , , id
            if (InStr(tables, id, true, 0))
            {
              WinGetPos, x, y, this_w, this_h, ahk_id%id%
              ;if (mouse_position_swap_method)
              ;{
                ;MouseGetPos, x, y
                ;Msgbox, %x%x%y%
              ;}
              ;else
              ;{
                x += border
                y += caption + border
              ;}
              o := 0
              Loop, %slotcount%
              {
                o += 1
                if (slot%o%id = id )
                {
                  oldslot := o
                  break
                }
              }
              
              
              c := slotcount + 1
              Loop, %slotcount%
              {
                c -= 1
                newslot := c
                if ((slot%c%x + border) > (x) )
                {
                  continue
                }
                else if ((slot%c%y + caption + border)> (y) )
                {
                  continue
                }
                else
                {
                  break
                }
              }
              t := slot%newslot%id
              slot%newslot%id := slot%oldslot%id 
              slot%oldslot%id := t
            }
          break
          }
        }
      }
    }
    else
    {
      ;do nothing
    }
  }
  
  
  
  c := 0
  Loop, %slotcount%
  {
    c += 1
    if (slot%c%id = "")
    {
      ;do nothing
    }
    else if (InStr(tables, slot%c%id, true, 0))
    {
      ;do nothing
    }
    else
    {
      slot%c%id := ""
    } 
  }
  
  
  Loop, parse, tables, `,
  {
    id := A_LoopField
    c := 0
    has_slot := 0
    custom := 1
    first_available := slotcount+1
    Loop, %slotcount%
    {
      c += 1
      c1 := c
      if (customfillorder)
      {
        c := IIf(ExFromList(customfillorder,c),ExFromList(customfillorder,c), c)
        if (slot%c%id = "" && GetItemPos(customfillorder,c) < first_available )
        {
          first_available := GetItemPos(customfillorder, c)
          custom := 1
        }
      }
      else if (slot%c%id = "" && c < first_available )
      {
        first_available := c
      }
      
      if (slot%c%id = id)
      {
        has_slot := 1
      }
      c := c1
    }
    
    if (first_available > slotcount && has_slot=0)
    {
      TrayTip, StarsPlanner, Too many tables, not enough slots, 10
      WinClose, ahk_id%id%
    }
    else if (has_slot=0)
    {
      if (custom)
      {
        first_available := ExFromList(customfillorder,first_available)
      }
      slot%first_available%id := id
    }
      
    c := 0
    Loop, %slotcount%
    {
      c += 1
      if (slot%c%id = id)
      {
        IfWinExist, ahk_id%id%
        {
          WinGet, m, MinMax, ahk_id%id%
          if (m != 0)
          {
            WinRestore, ahk_id%id%
            Sleep, -1
          }
          WinGetPos, , , this_w, this_h, ahk_id%id%
          if ((this_w > slot%c%w) || (this_w < slot%c%w) )
          {
            ;WinMove, ahk_id%id%, , 0, 0
            ;WinActivate,ahk_id%id%
            win_adjustsize(id, slot%c%w)
            Sleep, 40
          }
          WinGetPos, x, y, , , ahk_id%id%
          if (x != slot%c%x || y != slot%c%y)
          {
            WinMove, ahk_id%id%, , slot%c%x, slot%c%y
            Sleep, -1
            ControlSend, , {F5}, ahk_id%id%
          }
        }
        Else
        {
          slot%c%id := ""
        }
      }
    }
  }
}


fixtables_config()
{
  global slotcount
  global customfillorder
  WinGet, list, list, Stars Planner Slot #
  tables := ""
  Loop, %list%
  {
    tables := tables . "," . list%A_Index%
  }
  StringTrimLeft, tables, tables, 1
  t := ""
  
  
  GetKeyState, state, LButton
  if (state = "D")
  {
    MouseGetPos, , , id
    if (InStr(tables, id))
    {
      Sleep, 70
      GetKeyState, state, LButton
      if (state = "D")
      {
        Loop
        {
          Sleep, 10
          GetKeyState, state, LButton
          if (state = "U")
          {
            MouseGetPos, , , id
            if (InStr(tables, id, true, 0))
            {
              WinGetPos, x, y, this_w, this_h, ahk_id%id%
              
              o := 0
              Loop, %slotcount%
              {
                o += 1
                if (slot%o%id = id )
                {
                  oldslot := o
                  break
                }
              }
              
              
              c := slotcount + 1
              Loop, %slotcount%
              {
                c -= 1
                newslot := c
                if (slot%c%x  > (x) )
                {
                  continue
                }
                else if (slot%c%y  > (y) )
                {
                  continue
                }
                else
                {
                  break
                }
              }
              t := slot%newslot%id
              slot%newslot%id := slot%oldslot%id 
              slot%oldslot%id := t
            }
          break
          }
        }
      }
    }
    else
    {
      ;do nothing
    }
  }
  
  
  
  c := 0
  Loop, %slotcount%
  {
    c += 1
    if (slot%c%id = "")
    {
      ;do nothing
    }
    else if (InStr(tables, slot%c%id, true, 0))
    {
      ;do nothing
    }
    else
    {
      slot%c%id := ""
    } 
  }
  
  
  Loop, parse, tables, `,
  {
    id := A_LoopField
    c := 0
    has_slot := 0
    custom := 1
    first_available := slotcount+1
    Loop, %slotcount%
    {
      c += 1
      c1 := c
      if (customfillorder)
      {
        c := IIf(ExFromList(customfillorder,c),ExFromList(customfillorder,c), c)
        if (slot%c%id = "" && GetItemPos(customfillorder,c) < first_available )
        {
          first_available := GetItemPos(customfillorder, c)
          custom := 1
        }
      }
      else if (slot%c%id = "" && c < first_available )
      {
        first_available := c
      }
      
      if (slot%c%id = id)
      {
        has_slot := 1
      }
      c := c1
    }
    
    if (first_available > slotcount && has_slot=0)
    {
      TrayTip, StarsPlanner, Too many tables, not enough slots, 10
      WinClose, ahk_id%id%
    }
    else if (has_slot=0)
    {
      if (custom)
      {
        first_available := ExFromList(customfillorder,first_available)
      }
      slot%first_available%id := id
      
    }
      
    c := 0
    Loop, %slotcount%
    {
      c += 1
      if (slot%c%id = id)
      {
        IfWinExist, ahk_id%id%
        {
          WinGetPos, , , this_w, this_h, ahk_id%id%
          if ((this_w > slot%c%w) || (this_w < slot%c%w) )
          {
            WinMove, ahk_id%id%, , stot%c%x, slot%c%y, slot%c%w, slot%c%h
          }
          WinGetPos, x, y, , , ahk_id%id%
          
          if (x != slot%c%x || y != slot%c%y)
          {
            WinMove, ahk_id%id%, , slot%c%x, slot%c%y
          }
        }
        Else
        {
          slot%c%id := ""
        }
      }
    }
  }
}

;###########################################
;################# Lists ####################
;###########################################

;adds said item to the end of said list
AddToList(list,item,del=""){
del := IIf(del="",",",del)
If list =
 return item
return list . del . item
}

;return item at said position in said list
ExFromList(list,pos=1,del="") {
del := IIf(del,del,",")
StringSplit, item, list, %del%
return item%pos%
}

;removes said item from said list
RemoveFromList(list,item=1,del="") {
del := IIf(del,del,",")
If InStr(list, item . del)
 return StrRep(list, item . del, "", 0)
else if InStr(list, del . item, "", 0)
 return StrRep(list, del . item, "", 0)
else if (item = list)
 return
else
 return list
}

;removes the nth item from said list
RemoveItemNFromList(list,n,del="") {
del := IIf(del,del,",")
return RemoveFromList(list, ExFromList(list,n,del))
}

;returns the position of said item in said list
;(0 if not in list)
GetItemPos(list,item,del="") {
del := IIf(del,del,",")
StringSplit, array, list, %del%
Loop %array0% {
        If array%a_index% = %item%
                return a_index
 }
return 0
}

;inserts said item at said position in said list
InsertItem(list,item,pos,del="") {
del := IIf(del="",",",del)
StringSplit,array,list,%del%
Loop % IIf( ( pos < array0 ), array0, pos ) {
        thisItem := array%a_index%
        If ( a_index != pos )
                newList = %newList%%del%%thisItem%
        else
                newList = %newList%%del%%item%%del%%thisItem%
 }
If ( InStr(newList, ",",0,0) = StrLen(newList) )
 StringTrimRight, newList, newList, 1
StringTrimLeft, newList, newList, 1
return newList
}

;removes empty items (and trailing delimiters)
CleanList(list, del="") {
If del =
 del = `,
Loop {
  StringReplace, list, list, %del%%del%, %del%, UseErrorLevel
  If ! ErrorLevel
   break
 }
If InStr(list, del) = 1
 StringTrimLeft, list, list, 1
If InStr(list, del,0,0) = StrLen(list)
 StringTrimRight, list, list, 1
return list
}

List_longest(list, del="") {
del := IIf( del="", ",", del)
longest = 0
Loop, Parse, list, %del%
 {
        If (longest < StrLen(a_loopfield))
                longest := StrLen(a_loopfield)
 }
return longest
}


IIf(_boolExpr, _exprTrue, _exprFalse) {
If _boolExpr
 Return _exprTrue
else
 return _exprFalse
}

StrRep(str,char,rep_char="",all=1) {
StringReplace,str,str,%char%,%rep_char%,%all%
return str
}

relStarsClientPoint(id, ByRef x, ByRef y)
{
  global border
  global caption
  rw := 792
  rh := 546
  WinGetPos, , , w, h, ahk_id%id%
  w := w - (2*border)
  h := h - (2*border) - caption
  
  x := Floor( (x / rw ) * w )
  y := Floor( (y / rh) * h  )
  
}

relStarsScreenPoint(id, ByRef x, ByRef y)
{
  relStarsWindowPoint(id, x, y)
  WinGetPos, x1, y1, , , ahk_id%id%
  x += x1
  y += y1
}

relStarsWindowPoint(id, ByRef x, ByRef y)
{
  global border
  global caption
  relStarsClientPoint(id, x, y)
  x := x + border
  y := y + border + caption
}


GetPixelCount(x1, y1, x2, y2, color, options="")
{
  CoordMode, Pixel, Screen
  pixels := (x2 - x1 + 1)*(y2 - y1 + 1)
  If ( pixels <= 0 )
  {
    ErrorLevel = 1
    return
  }
  count = 0
  x = %x1%
  Loop
  {
    If ( x > x2 )
    {
      break
    }
    y = %y1%
    Loop
    {
      If ( y > y2 )
      {
        break
      }
      PixelGetColor, c, x, y, %options%
      If ( c = color )
      {
        count++
      }
      y++
    }
    x++
  }
  return count
}

;Juks rocks
PostLeftClick(x, y, table_id, activate=1) {
; ### JUK: Send the down left click, then the mouse-up messages.
; NOTE: This is relative to the top left of the client area and NOT the top left of the
;       window (ie: It *doesn't* include the title-bar like AHK's MouseClick does!!!).
If activate
 WinActivate, ahk_id%table_id%
PostMessage, 0x201, 0x0001, ((y<<16)^x), , ahk_id%table_id%
PostMessage, 0x202 , 0, ((y<<16)^x), , ahk_id%table_id%
}

PostStarsClick(x, y, id)
{
  relStarsClientPoint(id, x, y)
  PostLeftClick(x, y, id)
}


DoPlanning:
  fixtables()
return

DoPlanningConfig:
  fixtables_config()
return

KeepLobbyUp:
  WinGet, id, id, PokerStars Lobby
  WinGet, ismin, MinMax, ahk_id%id%
  tables := TableIDListAll()
  numtables := 0
  Loop, Parse, tables, `,
  {
    numtables += 1
  }
  if (PlanTables)
  {
    if ((numtables >= slotcount) && minimize_lobby_when_full)
    {
      if (ismin != -1)
      {
        WinMinimize, ahk_id%id%
      }
    }
    else
    {
      if (ismin = -1)
      {
        WinRestore, ahk_id%id%
      }
    }
  }  
  else
  {
    if (ismin = -1)
    {
      WinRestore, ahk_id%id%
    }
  }
    
  WinGet, ismin, MinMax, ahk_id%id%
  if (ismin = 0)
  {
    WinGetPos, lx, ly, , , ahk_id%id%
    if (lx != lobbyx || ly != lobbyy)
    {
      WinMove, ahk_id%id%, , %lobbyx%, %lobbyy%
    }
  }
   
return

KillPopUps:
  SetTitleMatchMode, 2
  
  WinGet, ps_id, id, PokerStars Lobby
  WinGet, ps_pid, PID, ahk_id%ps_id%
  
  IfWinExist, PokerStars ahk_class #32770 ahk_pid%ps_pid%
  {
    WinGet, idlist, list, PokerStars ahk_class #32770 ahk_pid%ps_pid%, , Lobby
    Loop, %idlist%
    {
      id := idlist%A_Index%
      WinGet, clist, ControlList, ahk_id%id%
      if (InStr(clist, "Button2"))
      {
        continue
      }
      else
      {
        Loop, 20
        {
          ;MsgBox, hhdjsak
          ;WinActivate, ahk_id%id%
          ControlFocus, Button1, ahk_id%id%
          ControlSend, Button1, {SPACE}, ahk_id%id%
          Sleep, 20
          IfWinNotExist, ahk_id%id%
          {
            ControlClick, Button1, ahk_id%id%
            break
          }
        }
        Sleep, 20
      }
    }
  }
  
  IfWinExist, Waiting List ahk_class #32770 ahk_pid%ps_pid%, Don't Join
  {
    WinGet, idlist, list, Waiting List ahk_class #32770 ahk_pid%ps_pid%, Don't Join
    Loop, %idlist%
    {