import os, sys
from UmenuUtils import Utils

class Menu(object):
    def __init__(self, basedir, mnustring, metadata, cnf):
        self.mnu = {}
        self.md = metadata
        self.mnu['mnustring'] = mnustring
        self.mnu['mnudir'] = basedir + Utils.mnustring2dir(mnustring)
        self.mnu['basedir'] = basedir
        self.mnu['data'] = self.data_dir_2_dict(self.mnu['mnudir'])
        if not self.mnu['data']:
            print('\n=============================================')
            if len(mnustring) == 1:
                print('There\'s no menu at {}.'.format(mnustring))
            else:
                print('Defective or no menu at {}.'.format(mnustring))
            print('Aborting.')
            print('=============================================\n')
            sys.exit(1)
            
        if(self.mnu['data']['type'] != 'm'):
            s='\nFATAL MENU CONF ERROR: Supposed menu has type \'{\'} instead of type \'{}\', aborting.\n'
            print(s.format(self.mnu['data']['type']))
        self.fixsort()
        self.mnu['kids'] = self.get_kids(self.mnu['mnudir'])
        self.mnu['sorted_ltrs'] = self.sort_letters()
        
        self.mnu['legalkeys'] = Menu.deepcopy(self.mnu['sorted_ltrs'])
        self.mnu['legalkeys'].append('=')
        self.mnu['legalkeys'].append(';')



    @classmethod
    def deepcopy(self, src):
        dst = []
        for elm in src:
            dst.append(elm)
        return dst

    def fixsort(self):
        if not 'sort' in self.mnu['data']:
            self.mnu['data']['sort'] = '-'
        elif self.mnu['data']['sort'] == '':
            self.mnu['data']['sort'] = '-'


    def sort_letters(self):
        orderstring = self.mnu['data']['sort']
        ltrdict = {}
        for ltr in self.mnu['kids'].keys():
            ltrdict[ltr] = 1
        tempstor = {'leaders': [], 'remainder': [], 'followers': []}
        group = 'leaders'
        while len(orderstring) > 0:
            ch = orderstring[0]
            orderstring = orderstring[1:]
            if ch == '-':
                group = 'followers'
            else:
                if ch in ltrdict:
                    del(ltrdict[ch])
                    (tempstor[group]).append(ch)
        tempstor['remainder'] = sorted(ltrdict.keys())
        groups=['leaders', 'remainder', 'followers']

        rtrnlist = []
        for group in groups:
            for ch in tempstor[group]:
                rtrnlist.append(ch)
        self.mnu['sorted_ltrs'] = rtrnlist
        return (rtrnlist)




    def render(self):
        from UmenuLicense import License
        lic = License()
        s='       UMENU2 menu system (version {}), (C) 2016 by Steve Litt'
        print(s.format(lic.version()))
        s = 'NO WARRANTY! Licensed under the GNU GPL Version 3. See the COPYING file.'

        print(s.format(lic.tinyname))
        print('')
        s='*****  {}  *****          [{}]'
        s=s.format(self.mnu['data']['menutitle'], self.mnu['mnustring'])
        print(s)
        print('')
        for ltr in self.mnu['sorted_ltrs']:
            ctitle=self.mnu['kids'][ltr]['choicetitle']
            thetype=self.mnu['kids'][ltr]['type']
            if thetype == 'm':
                prefix = '...'
            elif thetype == 'r':
                prefix = '  ^'
            else:
                prefix = '   '
            line='{}  {}: {}'.format(prefix, str.upper(ltr), ctitle)
            print(line)
        Utils.printraw('Your choice please==>')


    def handle_letter(self, ltr):
        if ltr == '=':
            self.next = {'type': '='}
        elif ltr == ';':
            self.next = {'type': ';'}
        else:
            nxdir = self.mnu['mnudir'] + '/' + ltr
            self.next = self.data_dir_2_dict(nxdir)

    def data_dir_2_dict(self, thedir):
        d = {}
        thedir = thedir + '/data'
        try:
            listt = os.listdir(thedir)
        except:
            return None
        for fname in listt:
            #if not fname[0] == '.':      ### Hack to ignore Vim backup files
            if fname in self.md.props:      ### Only authorized properties
                if self.md.props[fname]['needed'] != 'n':  ### Only properties need for this choice type                                      
                    if self.md.props[fname]['listok'][0]:
                        val = Utils.dsnag_multi(thedir, fname)
                    else:
                        val = Utils.dsnag(thedir, fname)
                    d[fname] = val
        return d


    def get_kids(self, mnudir):
        kids = {}
        for fname in os.listdir(mnudir):
            if len(fname) == 1 and fname.islower():
                kids[fname] = self.data_dir_2_dict(mnudir + '/' + fname)
        return(kids)


    def get_user_input(self):
        while True:
            ltr = Utils.getch_unix().lower()
            if ltr in self.mnu['legalkeys']:
                print('')
                return ltr
            s='({}) Your choice please==>'
            Utils.printraw('    \r                                                 \r')
            Utils.printraw(s.format(''.join(self.mnu['legalkeys'])))

# /* vim: set foldmethod=indent: */
