from collections import OrderedDict
import csv
from sys import platform
from functools import partial
import time
if __debug__:
    from traceback import print_exc

import Tkinter as tk
import ttk
import myNotebook as nb

import companion
from companion import ship_map
from l10n import Locale
from monitor import monitor
import prefs

if platform=='win32':
    import ctypes
    from ctypes.wintypes import *
    GetParent = ctypes.windll.user32.GetParent
    GetParent.argtypes = [HWND]
    GetWindowRect = ctypes.windll.user32.GetWindowRect
    GetWindowRect.argtypes = [HWND, ctypes.POINTER(RECT)]
    CalculatePopupWindowPosition = ctypes.windll.user32.CalculatePopupWindowPosition
    CalculatePopupWindowPosition.argtypes = [ctypes.POINTER(POINT), ctypes.POINTER(SIZE), UINT, ctypes.POINTER(RECT), ctypes.POINTER(RECT)]

RANKS = [	# in output order
    (_('Combat')     , 'combat'),	# Ranking
    (_('Trade')      , 'trade'),	# Ranking
    (_('Explorer')   , 'explore'),	# Ranking
    (_('CQC')        , 'cqc'),		# Ranking
    (_('Federation') , 'federation'),	# Ranking
    (_('Empire')     , 'empire'),	# Ranking
    (_('Powerplay')  , 'power'),	# Ranking
    # ???            , 'crime'),	# Ranking
    # ???            , 'service'),	# Ranking
]

RANK_NAMES = {

    # http://elite-dangerous.wikia.com/wiki/Pilots_Federation#Ranks
    'combat'     : [_('Harmless'),		# Combat rank
                    _('Mostly Harmless'),	# Combat rank
                    _('Novice'),		# Combat rank
                    _('Competent'),		# Combat rank
                    _('Expert'),		# Combat rank
                    _('Master'),		# Combat rank
                    _('Dangerous'),		# Combat rank
                    _('Deadly'),		# Combat rank
                    _('Elite')],		# Top rank
    'trade'      : [_('Penniless'),		# Trade rank
                    _('Mostly Penniless'),	# Trade rank
                    _('Peddler'),		# Trade rank
                    _('Dealer'),		# Trade rank
                    _('Merchant'),		# Trade rank
                    _('Broker'),		# Trade rank
                    _('Entrepreneur'),		# Trade rank
                    _('Tycoon'),		# Trade rank
                    _('Elite')],		# Top rank
    'explore'    : [_('Aimless'),		# Explorer rank
                    _('Mostly Aimless'),	# Explorer rank
                    _('Scout'),			# Explorer rank
                    _('Surveyor'),		# Explorer rank
                    _('Trailblazer'),		# Explorer rank
                    _('Pathfinder'),		# Explorer rank
                    _('Ranger'),		# Explorer rank
                    _('Pioneer'),		# Explorer rank
                    _('Elite')],		# Top rank
    'cqc'        : [_('Helpless'),		# CQC rank
                    _('Mostly Helpless'),	# CQC rank
                    _('Amateur'),		# CQC rank
                    _('Semi Professional'),	# CQC rank
                    _('Professional'),		# CQC rank
                    _('Champion'),		# CQC rank
                    _('Hero'),			# CQC rank
                    _('Gladiator'),		# CQC rank
                    _('Elite')],		# Top rank

    # http://elite-dangerous.wikia.com/wiki/Federation#Ranks
    'federation' : [_('None'),			# No rank
                    _('Recruit'),		# Federation rank
                    _('Cadet'),			# Federation rank
                    _('Midshipman'),		# Federation rank
                    _('Petty Officer'),		# Federation rank
                    _('Chief Petty Officer'),	# Federation rank
                    _('Warrant Officer'),	# Federation rank
                    _('Ensign'),		# Federation rank
                    _('Lieutenant'),		# Federation rank
                    _('Lieutenant Commander'),	# Federation rank
                    _('Post Commander'),	# Federation rank
                    _('Post Captain'),		# Federation rank
                    _('Rear Admiral'),		# Federation rank
                    _('Vice Admiral'),		# Federation rank
                    _('Admiral')],		# Federation rank

    # http://elite-dangerous.wikia.com/wiki/Empire#Ranks
    'empire'     : [_('None'),			# No rank
                    _('Outsider'),		# Empire rank
                    _('Serf'),			# Empire rank
                    _('Master'),		# Empire rank
                    _('Squire'),		# Empire rank
                    _('Knight'),		# Empire rank
                    _('Lord'),			# Empire rank
                    _('Baron'),			# Empire rank
                    _('Viscount'),		# Empire rank
                    _('Count'),			# Empire rank
                    _('Earl'),			# Empire rank
                    _('Marquis'),		# Empire rank
                    _('Duke'),			# Empire rank
                    _('Prince'),		# Empire rank
                    _('King')],			# Empire rank

    # http://elite-dangerous.wikia.com/wiki/Ratings
    'power'      : [_('None'),			# No rank
                    _('Rating 1'),		# Power rank
                    _('Rating 2'),		# Power rank
                    _('Rating 3'),		# Power rank
                    _('Rating 4'),		# Power rank
                    _('Rating 5')],		# Power rank
}


def status(data):

    # StatsResults assumes these three things are first
    res = [ [_('Cmdr'),    data['commander']['name']],
            [_('Balance'), str(data['commander'].get('credits', 0))],	# Cmdr stats
            [_('Loan'),    str(data['commander'].get('debt', 0))],	# Cmdr stats
    ]

    ranks = data['commander'].get('rank', {})
    for title, thing in RANKS:
        rank = ranks.get(thing)
        names = RANK_NAMES[thing]
        if isinstance(rank, int):
            res.append([title, rank < len(names) and names[rank] or ('Rank %d' % rank)])
        else:
            res.append([title, _('None')])	# No rank

    return res


def export_status(data, filename):
    h = csv.writer(open(filename, 'wb'))
    h.writerow(['Category', 'Value'])
    for thing in status(data):
        h.writerow([x.encode('utf-8') for x in thing])


# Returns id,name,shipName,system,station,value
def ships(data):

    ships = companion.listify(data.get('ships'))
    current = data['commander'].get('currentShipId')

    if isinstance(current, int) and current < len(ships) and ships[current]:
        ships.insert(0, ships.pop(current))	# Put current ship first

        if not data['commander'].get('docked'):
            # Set current system, not last docked
            return ([ (str(ships[0]['id']), ship_map.get(ships[0]['name'].lower(), ships[0]['name']), ships[0].get('shipName', ''), data['lastSystem']['name'], '', str(ships[0]['value']['total'])) ] +
                    [ (str(ship['id']), ship_map.get(ship['name'].lower(), ship['name']), ship.get('shipName', ''), ship['starsystem']['name'], ship['station']['name'], str(ship['value']['total'])) for ship in ships[1:] if ship])

    return [ (str(ship['id']), ship_map.get(ship['name'].lower(), ship['name']), ship.get('shipName', ''), ship['starsystem']['name'], ship['station']['name'], str(ship['value']['total'])) for ship in ships if ship]

def export_ships(data, filename):
    h = csv.writer(open(filename, 'wb'))
    h.writerow(['Id', 'Ship', 'Name', 'System', 'Station', 'Value'])
    for thing in ships(data):
        h.writerow([x.encode('utf-8') for x in thing])


class StatsDialog():

    def __init__(self, app):
        self.parent = app.w
        self.status = app.status
        self.verify = app.verify
        self.showstats()

    def showstats(self):
        if not monitor.cmdr:
            return

        self.status['text'] = _('Fetching data...')
        self.parent.update_idletasks()

        try:
            data = companion.session.profile()
        except companion.VerificationRequired:
            return prefs.AuthenticationDialog(self.parent, partial(self.verify, self.showstats))
        except companion.ServerError as e:
            self.status['text'] = str(e)
            return
        except Exception as e:
            if __debug__: print_exc()
            self.status['text'] = str(e)
            return

        if not data.get('commander') or not data['commander'].get('name','').strip():
            self.status['text'] = _("Who are you?!")		# Shouldn't happen
        elif not data.get('lastSystem') or not data['lastSystem'].get('name','').strip() or not data.get('lastStarport') or not data['lastStarport'].get('name','').strip():
            self.status['text'] = _("Where are you?!")		# Shouldn't happen
        elif not data.get('ship') or not data['ship'].get('modules') or not data['ship'].get('name','').strip():
            self.status['text'] = _("What are you flying?!")	# Shouldn't happen
        else:
            self.status['text'] = ''
            StatsResults(self.parent, data)


class StatsResults(tk.Toplevel):

    def __init__(self, parent, data):
        tk.Toplevel.__init__(self, parent)

        self.parent = parent

        stats = status(data)
        self.title(' '.join(stats[0]))	# assumes first thing is player name

        if parent.winfo_viewable():
            self.transient(parent)

        # position over parent
        if platform!='darwin' or parent.winfo_rooty()>0:	# http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7
            self.geometry("+%d+%d" % (parent.winfo_rootx(), parent.winfo_rooty()))

        # remove decoration
        self.resizable(tk.FALSE, tk.FALSE)
        if platform=='win32':
            self.attributes('-toolwindow', tk.TRUE)
        elif platform=='darwin':
            # http://wiki.tcl.tk/13428
            parent.call('tk::unsupported::MacWindowStyle', 'style', self, 'utility')

        frame = ttk.Frame(self)
        frame.grid(sticky=tk.NSEW)

        notebook = nb.Notebook(frame)

        page = self.addpage(notebook)
        for thing in stats[1:3]:
            self.addpagerow(page, [thing[0], self.credits(int(thing[1]))])	# assumes things two and three are money
        for thing in stats[3:]:
            self.addpagerow(page, thing)
        ttk.Frame(page).grid(pady=5)			# bottom spacer
        notebook.add(page, text=_('Status'))		# Status dialog title

        page = self.addpage(notebook, [
            _('Ship'),		# Status dialog subtitle
            '',
            _('System'),	# Main window
            _('Station'),	# Status dialog subtitle
            _('Value'),		# Status dialog subtitle - CR value of ship
        ])
        shiplist = ships(data)
        for thing in shiplist:
            self.addpagerow(page, list(thing[1:-1]) + [self.credits(int(thing[-1]))])	# skip id, last item is money
        ttk.Frame(page).grid(pady=5)			# bottom spacer
        notebook.add(page, text=_('Ships'))		# Status dialog title

        if platform!='darwin':
            buttonframe = ttk.Frame(frame)
            buttonframe.grid(padx=10, pady=(0,10), sticky=tk.NSEW)
            buttonframe.columnconfigure(0, weight=1)
            ttk.Label(buttonframe).grid(row=0, column=0)	# spacer
            ttk.Button(buttonframe, text='OK', command=self.destroy).grid(row=0, column=1, sticky=tk.E)

        # wait for window to appear on screen before calling grab_set
        self.wait_visibility()
        self.grab_set()

        # Ensure fully on-screen
        if platform == 'win32':
            position = RECT()
            GetWindowRect(GetParent(self.winfo_id()), position)
            if CalculatePopupWindowPosition(POINT(parent.winfo_rootx(), parent.winfo_rooty()),
                                            SIZE(position.right - position.left, position.bottom - position.top),
                                            0x10000, None, position):
                self.geometry("+%d+%d" % (position.left, position.top))

    def addpage(self, parent, header=[], align=None):
        page = nb.Frame(parent)
        page.grid(pady=10, sticky=tk.NSEW)
        page.columnconfigure(0, weight=1)
        if header:
            self.addpageheader(page, header, align=align)
        return page

    def addpageheader(self, parent, header, align=None):
        self.addpagerow(parent, header, align=align)
        ttk.Separator(parent, orient=tk.HORIZONTAL).grid(columnspan=len(header), padx=10, pady=2, sticky=tk.EW)

    def addpagespacer(self, parent):
        self.addpagerow(parent, [''])

    def addpagerow(self, parent, content, align=None):
        for i in range(len(content)):
            label = nb.Label(parent, text=content[i])
            if i == 0:
                label.grid(padx=10, sticky=tk.W)
                row = parent.grid_size()[1]-1
            elif align is None and i == len(content) - 1:	# Assumes last column right justified if unspecified
                label.grid(row=row, column=i, padx=10, sticky=tk.E)
            else:
                label.grid(row=row, column=i, padx=10, sticky=align or tk.W)

    def credits(self, value):
        return Locale.stringFromNumber(value, 0) + ' Cr'


from collections import OrderedDict
import csv
from sys import platform
from functools import partial
import time
if __debug__:
    from traceback import print_exc

import Tkinter as tk
import ttk
import myNotebook as nb

import companion
from companion import ship_map
from l10n import Locale
from monitor import monitor
import prefs

if platform=='win32':
    import ctypes
    from ctypes.wintypes import *
    GetParent = ctypes.windll.user32.GetParent
    GetParent.argtypes = [HWND]
    GetWindowRect = ctypes.windll.user32.GetWindowRect
    GetWindowRect.argtypes = [HWND, ctypes.POINTER(RECT)]
    CalculatePopupWindowPosition = ctypes.windll.user32.CalculatePopupWindowPosition
    CalculatePopupWindowPosition.argtypes = [ctypes.POINTER(POINT), ctypes.POINTER(SIZE), UINT, ctypes.POINTER(RECT), ctypes.POINTER(RECT)]

RANKS = [	# in output order
    (_('Combat')     , 'combat'),	# Ranking
    (_('Trade')      , 'trade'),	# Ranking
    (_('Explorer')   , 'explore'),	# Ranking
    (_('CQC')        , 'cqc'),		# Ranking
    (_('Federation') , 'federation'),	# Ranking
    (_('Empire')     , 'empire'),	# Ranking
    (_('Powerplay')  , 'power'),	# Ranking
    # ???            , 'crime'),	# Ranking
    # ???            , 'service'),	# Ranking
]

RANK_NAMES = {

    # http://elite-dangerous.wikia.com/wiki/Pilots_Federation#Ranks
    'combat'     : [_('Harmless'),		# Combat rank
                    _('Mostly Harmless'),	# Combat rank
                    _('Novice'),		# Combat rank
                    _('Competent'),		# Combat rank
                    _('Expert'),		# Combat rank
                    _('Master'),		# Combat rank
                    _('Dangerous'),		# Combat rank
                    _('Deadly'),		# Combat rank
                    _('Elite')],		# Top rank
    'trade'      : [_('Penniless'),		# Trade rank
                    _('Mostly Penniless'),	# Trade rank
                    _('Peddler'),		# Trade rank
                    _('Dealer'),		# Trade rank
                    _('Merchant'),		# Trade rank
                    _('Broker'),		# Trade rank
                    _('Entrepreneur'),		# Trade rank
                    _('Tycoon'),		# Trade rank
                    _('Elite')],		# Top rank
    'explore'    : [_('Aimless'),		# Explorer rank
                    _('Mostly Aimless'),	# Explorer rank
                    _('Scout'),			# Explorer rank
                    _('Surveyor'),		# Explorer rank
                    _('Trailblazer'),		# Explorer rank
                    _('Pathfinder'),		# Explorer rank
                    _('Ranger'),		# Explorer rank
                    _('Pioneer'),		# Explorer rank
                    _('Elite')],		# Top rank
    'cqc'        : [_('Helpless'),		# CQC rank
                    _('Mostly Helpless'),	# CQC rank
                    _('Amateur'),		# CQC rank
                    _('Semi Professional'),	# CQC rank
                    _('Professional'),		# CQC rank
                    _('Champion'),		# CQC rank
                    _('Hero'),			# CQC rank
                    _('Gladiator'),		# CQC rank
                    _('Elite')],		# Top rank

    # http://elite-dangerous.wikia.com/wiki/Federation#Ranks
    'federation' : [_('None'),			# No rank
                    _('Recruit'),		# Federation rank
                    _('Cadet'),			# Federation rank
                    _('Midshipman'),		# Federation rank
                    _('Petty Officer'),		# Federation rank
                    _('Chief Petty Officer'),	# Federation rank
                    _('Warrant Officer'),	# Federation rank
                    _('Ensign'),		# Federation rank
                    _('Lieutenant'),		# Federation rank
                    _('Lieutenant Commander'),	# Federation rank
                    _('Post Commander'),	# Federation rank
                    _('Post Captain'),		# Federation rank
                    _('Rear Admiral'),		# Federation rank
                    _('Vice Admiral'),		# Federation rank
                    _('Admiral')],		# Federation rank

    # http://elite-dangerous.wikia.com/wiki/Empire#Ranks
    'empire'     : [_('None'),			# No rank
                    _('Outsider'),		# Empire rank
                    _('Serf'),			# Empire rank
                    _('Master'),		# Empire rank
                    _('Squire'),		# Empire rank
                    _('Knight'),		# Empire rank
                    _('Lord'),			# Empire rank
                    _('Baron'),			# Empire rank
                    _('Viscount'),		# Empire rank
                    _('Count'),			# Empire rank
                    _('Earl'),			# Empire rank
                    _('Marquis'),		# Empire rank
                    _('Duke'),			# Empire rank
                    _('Prince'),		# Empire rank
                    _('King')],			# Empire rank

    # http://elite-dangerous.wikia.com/wiki/Ratings
    'power'      : [_('None'),			# No rank
                    _('Rating 1'),		# Power rank
                    _('Rating 2'),		# Power rank
                    _('Rating 3'),		# Power rank
                    _('Rating 4'),		# Power rank
                    _('Rating 5')],		# Power rank
}


def status(data):

    # StatsResults assumes these three things are first
    res = [ [_('Cmdr'),    data['commander']['name']],
            [_('Balance'), str(data['commander'].get('credits', 0))],	# Cmdr stats
            [_('Loan'),    str(data['commander'].get('debt', 0))],	# Cmdr stats
    ]

    ranks = data['commander'].get('rank', {})
    for title, thing in RANKS:
        rank = ranks.get(thing)
        names = RANK_NAMES[thing]
        if isinstance(rank, int):
            res.append([title, rank < len(names) and names[rank] or ('Rank %d' % rank)])
        else:
            res.append([title, _('None')])	# No rank

    return res


def export_status(data, filename):
    h = csv.writer(open(filename, 'wb'))
    h.writerow(['Category', 'Value'])
    for thing in status(data):
        h.writerow([x.encode('utf-8') for x in thing])


# Returns id,name,shipName,system,station,value
def ships(data):

    ships = companion.listify(data.get('ships'))
    current = data['commander'].get('currentShipId')

    if isinstance(current, int) and current < len(ships) and ships[current]:
        ships.insert(0, ships.pop(current))	# Put current ship first

        if not data['commander'].get('docked'):
            # Set current system, not last docked
            return ([ (str(ships[0]['id']), ship_map.get(ships[0]['name'].lower(), ships[0]['name']), ships[0].get('shipName', ''), data['lastSystem']['name'], '', str(ships[0]['value']['total'])) ] +
                    [ (str(ship['id']), ship_map.get(ship['name'].lower(), ship['name']), ship.get('shipName', ''), ship['starsystem']['name'], ship['station']['name'], str(ship['value']['total'])) for ship in ships[1:] if ship])

    return [ (str(ship['id']), ship_map.get(ship['name'].lower(), ship['name']), ship.get('shipName', ''), ship['starsystem']['name'], ship['station']['name'], str(ship['value']['total'])) for ship in ships if ship]

def export_ships(data, filename):
    h = csv.writer(open(filename, 'wb'))
    h.writerow(['Id', 'Ship', 'Name', 'System', 'Station', 'Value'])
    for thing in ships(data):
        h.writerow([x.encode('utf-8') for x in thing])


class StatsDialog():

    def __init__(self, app):
        self.parent = app.w
        self.status = app.status
        self.verify = app.verify
        self.showstats()

    def showstats(self):
        if not monitor.cmdr:
            return

        self.status['text'] = _('Fetching data...')
        self.parent.update_idletasks()

        try:
            data = companion.session.profile()
        except companion.VerificationRequired:
            return prefs.AuthenticationDialog(self.parent, partial(self.verify, self.showstats))
        except companion.ServerError as e:
            self.status['text'] = str(e)
            return
        except Exception as e:
            if __debug__: print_exc()
            self.status['text'] = str(e)
            return

        if not data.get('commander') or not data['commander'].get('name','').strip():
            self.status['text'] = _("Who are you?!")		# Shouldn't happen
        elif not data.get('lastSystem') or not data['lastSystem'].get('name','').strip() or not data.get('lastStarport') or not data['lastStarport'].get('name','').strip():
            self.status['text'] = _("Where are you?!")		# Shouldn't happen
        elif not data.get('ship') or not data['ship'].get('modules') or not data['ship'].get('name','').strip():
            self.status['text'] = _("What are you flying?!")	# Shouldn't happen
        else:
            self.status['text'] = ''
            StatsResults(self.parent, data)


class StatsResults(tk.Toplevel):

    def __init__(self, parent, data):
        tk.Toplevel.__init__(self, parent)

        self.parent = parent

        stats = status(data)
        self.title(' '.join(stats[0]))	# assumes first thing is player name

        if parent.winfo_viewable():
            self.transient(parent)

        # position over parent
        if platform!='darwin' or parent.winfo_rooty()>0:	# http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7
            self.geometry("+%d+%d" % (parent.winfo_rootx(), parent.winfo_rooty()))

        # remove decoration
        self.resizable(tk.FALSE, tk.FALSE)
        if platform=='win32':
            self.attributes('-toolwindow', tk.TRUE)
        elif platform=='darwin':
            # http://wiki.tcl.tk/13428
            parent.call('tk::unsupported::MacWindowStyle', 'style', self, 'utility')

        frame = ttk.Frame(self)
        frame.grid(sticky=tk.NSEW)

        notebook = nb.Notebook(frame)

        page = self.addpage(notebook)
        for thing in stats[1:3]:
            self.addpagerow(page, [thing[0], self.credits(int(thing[1]))])	# assumes things two and three are money
        for thing in stats[3:]:
            self.addpagerow(page, thing)
        ttk.Frame(page).grid(pady=5)			# bottom spacer
        notebook.add(page, text=_('Status'))		# Status dialog title

        page = self.addpage(notebook, [
            _('Ship'),		# Status dialog subtitle
            '',
            _('System'),	# Main window
            _('Station'),	# Status dialog subtitle
            _('Value'),		# Status dialog subtitle - CR value of ship
        ])
        shiplist = ships(data)
        for thing in shiplist:
            self.addpagerow(page, list(thing[1:-1]) + [self.credits(int(thing[-1]))])	# skip id, last item is money
        ttk.Frame(page).grid(pady=5)			# bottom spacer
        notebook.add(page, text=_('Ships'))		# Status dialog title

        if platform!='darwin':
            buttonframe = ttk.Frame(frame)
            buttonframe.grid(padx=10, pady=(0,10), sticky=tk.NSEW)
            buttonframe.columnconfigure(0, weight=1)
            ttk.Label(buttonframe).grid(row=0, column=0)	# spacer
            ttk.Button(buttonframe, text='OK', command=self.destroy).grid(row=0, column=1, sticky=tk.E)

        # wait for window to appear on screen before calling grab_set
        self.wait_visibility()
        self.grab_set()

        # Ensure fully on-screen
        if platform == 'win32':
            position = RECT()
            GetWindowRect(GetParent(self.winfo_id()), position)
            if CalculatePopupWindowPosition(POINT(parent.winfo_rootx(), parent.winfo_rooty()),
                                            SIZE(position.right - position.left, position.bottom - position.top),
                                            0x10000, None, position):
                self.geometry("+%d+%d" % (position.left, position.top))

    def addpage(self, parent, header=[], align=None):
        page = nb.Frame(parent)
        page.grid(pady=10, sticky=tk.NSEW)
        page.columnconfigure(0, weight=1)
        if header:
            self.addpageheader(page, header, align=align)
        return page

    def addpageheader(self, parent, header, align=None):
        self.addpagerow(parent, header, align=align)
        ttk.Separator(parent, orient=tk.HORIZONTAL).grid(columnspan=len(header), padx=10, pady=2, sticky=tk.EW)

    def addpagespacer(self, parent):
        self.addpagerow(parent, [''])

    def addpagerow(self, parent, content, align=None):
        for i in range(len(content)):
            label = nb.Label(parent, text=content[i])
            if i == 0:
                label.grid(padx=10, sticky=tk.W)
                row = parent.grid_size()[1]-1
            elif align is None and i == len(content) - 1:	# Assumes last column right justified if unspecified
                label.grid(row=row, column=i, padx=10, sticky=tk.E)
            else:
                label.grid(row=row, column=i, padx=10, sticky=align or tk.W)

    def credits(self, value):
        return Locale.stringFromNumber(value, 0) + ' Cr'


# in output order # Ranking # Ranking # Ranking # Ranking # Ranking # Ranking # Ranking # ???            , 'crime'),	# Ranking # ???            , 'service'),	# Ranking # http://elite-dangerous.wikia.com/wiki/Pilots_Federation#Ranks # Combat rank # Combat rank # Combat rank # Combat rank # Combat rank # Combat rank # Combat rank # Combat rank # Top rank # Trade rank # Trade rank # Trade rank # Trade rank # Trade rank # Trade rank # Trade rank # Trade rank # Top rank # Explorer rank # Explorer rank # Explorer rank # Explorer rank # Explorer rank # Explorer rank # Explorer rank # Explorer rank # Top rank # CQC rank # CQC rank # CQC rank # CQC rank # CQC rank # CQC rank # CQC rank # CQC rank # Top rank # http://elite-dangerous.wikia.com/wiki/Federation#Ranks # No rank # Federation rank # Federation rank # Federation rank # Federation rank # Federation rank # Federation rank # Federation rank # Federation rank # Federation rank # Federation rank # Federation rank # Federation rank # Federation rank # Federation rank # http://elite-dangerous.wikia.com/wiki/Empire#Ranks # No rank # Empire rank # Empire rank # Empire rank # Empire rank # Empire rank # Empire rank # Empire rank # Empire rank # Empire rank # Empire rank # Empire rank # Empire rank # Empire rank # Empire rank # http://elite-dangerous.wikia.com/wiki/Ratings # No rank # Power rank # Power rank # Power rank # Power rank # Power rank # StatsResults assumes these three things are first # Cmdr stats # Cmdr stats # No rank # Returns id,name,shipName,system,station,value # Put current ship first # Set current system, not last docked # Shouldn't happen # Shouldn't happen # Shouldn't happen # assumes first thing is player name # position over parent # http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7 # remove decoration # http://wiki.tcl.tk/13428 # assumes things two and three are money # bottom spacer # Status dialog title # Status dialog subtitle # Main window # Status dialog subtitle # Status dialog subtitle - CR value of ship # skip id, last item is money # bottom spacer # Status dialog title # spacer # wait for window to appear on screen before calling grab_set # Ensure fully on-screen # Assumes last column right justified if unspecified