#!/usr/bin/python3
# -*- coding: utf-8 -*-

#  Copyright © 2012-2013  B. Clausius <barcc@gmx.de>
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.


import sys, os, subprocess


rotation_symbolic_compact_to_idxrot = {
        "":"",          "ff":"FF",      "ll":"LL",      "uu":"UU",
        "f":"F",        "f'":"B",       "fuu":"UUB",    "fll":"UUF",
        "ffu":"ULL",    "u":"U",        "u'":"D",       "ffu'":"UFF",
        "fu":"UL",      "f'u":"UR",     "fu'":"FD",     "f'u'":"LB",
        "f'l'":"DB",    "uf":"UF",      "fl":"LD",      "lu":"UB",
        "l'":"R",       "ffl'":"UUL",   "l":"L",        "ffl":"UUR",
    }
    
def indices_compact_to_index(indices, size):
    indices = tuple(indices)
    for b in range(size * size * size):
        bindices = (b % size, b // size % size, b // size // size)
        if bindices == indices:
            return b
    raise ValueError('Invalid block indices:', indices)
    
def index_compact_to_indices(index, size):
    return index % size, index // size % size, index // size // size
    
def block_compact_to_index_rot(block, size):
    # every block is stored as 4-tuple (x,y,z,sym), where sym is a symbolic rotation
    block = block.strip().split(',')
    x, y, z, rot = block
    x, y, z = int(x), int(y), int(z)
    x, y, z = y, size-1 - z, size-1 - x
    indices = x, y, z
    try:
        rot = rotation_symbolic_compact_to_idxrot[rot]
    except KeyError:
        raise ValueError('Invalid block rotation:', rot)
    index = indices_compact_to_index(indices, size)
    return '{}-{}'.format(index, rot)
    
def blocks_compact_to_index_rot(blocks, size):
    def blocks_perm(index):
        x, y, z = index_compact_to_indices(index, size)
        x, y, z = size-1 - z, x, size-1 - y
        index = indices_compact_to_index((x, y, z), size)
        return blocks[index]
    blocks = blocks.strip().split(' ')
    for i, block in enumerate(blocks):
        blocks[i] = block_compact_to_index_rot(block, size)
    blocks = [blocks_perm(i) for i, unused_b in enumerate(blocks)]
    return ' '.join(blocks)
    
def parse_initial_state(state):
    msf, blocks = state.split(':', 1)
    model, size, bformat = msf.split(' ', 2)
    if model != 'Cube':
        print('Unknown model:', repr(model))
        print('  Fallback:', 'Cube', 3, 'solved')
        return 'Cube', 3, 'solved'
    try:
        size = int(size)
    except ValueError:
        print('Unknown size:', repr(size))
        print('  Fallback:', 'Cube', 3, 'solved')
        return 'Cube', 3, 'solved'
    if bformat == 'identity':
        blocks = 'solved'
    elif bformat == 'blocks_compact':
        blocks = 'idx-rot: ' + blocks_compact_to_index_rot(blocks, size)
    else:
        blocks = 'solved'
    return model, size, blocks
    
def gconf_0_5_to_settings_1_0(settings_file):
    path_to_face = {#'/apps/pybik': None,
                    #'/apps/pybik/colors:': None,
                    '/apps/pybik/colors/0:': 0,
                    '/apps/pybik/colors/1:': 1,
                    '/apps/pybik/colors/2:': 2,
                    '/apps/pybik/colors/3:': 3,
                    '/apps/pybik/colors/4:': 4,
                    '/apps/pybik/colors/5:': 5,
                }
    path = '/apps/pybik'
    try:
        process = subprocess.Popen(['gconftool', '--recursive-list', path], stdout=subprocess.PIPE, universal_newlines=True)
    except OSError:
        return
    lines = process.communicate()[0]
    settings_dir = os.path.dirname(settings_file)
    if settings_dir and not os.path.exists(settings_dir):
        os.makedirs(settings_dir)
    with open(settings_file, 'wt', encoding='utf-8') as settings:
        face = 0
        for line in lines.splitlines():
            line = line.strip()
            face = path_to_face.get(line, face)
            if '=' not in line:
                facetype = None
                pattern = None
                imagefile = None
                imagemode = None
                continue
            key, value = line.split('=', 1)
            key = key.strip()
            value = value.strip()
            # pylint: disable=C0321
            if   key == 'saved_pos':        print('game.position =', value, file=settings)
            elif key == 'selection_mode':
                value = 'quadrant' if value == '0' else 'simple'
                print('draw.selection =', repr(value), file=settings)
            elif key == 'saved_moves':      print('game.moves =', repr('native: '+value), file=settings)
            elif key == 'lighting':         print('draw.lighting =', value=='true', file=settings)
            elif key == 'background_color': print('theme.bgcolor =', repr(value), file=settings)
            elif key == 'saved_state':
                if value:
                    mtype, size, blocks = parse_initial_state(value)
                    print('game.type =', repr(mtype), file=settings)
                    print('game.size =', (size, size, size), file=settings)
                    print('game.blocks =', repr(blocks), file=settings)
            elif key == 'color':            print('theme.face.%s.color =' % face, repr(value), file=settings)
            elif key == 'facetype':
                facetype = value
                if facetype == '1' and pattern is not None:
                    print('theme.face.%s.image =' % face, repr(pattern), file=settings)
                if facetype == '2' and imagefile is not None:
                    print('theme.face.%s.image =' % face, repr(imagefile), file=settings)
                if facetype == '2' and imagemode is not None:
                    print('theme.face.%s.mode =' % face, repr(imagemode), file=settings)
            elif key == 'pattern':
                if   value == '0': pattern = 'BEAMED EIGHTH NOTES.png'
                elif value == '1': pattern = 'diagonal-lines.png'
                elif value == '2': pattern = 'WHITE SMILING FACE.png'
                elif value == '3': pattern = 'BLACK SMILING FACE.png'
                elif value == '4': pattern = 'squares.png'
                elif value == '5': pattern = 'WHITE SUN WITH RAYS.png'
                if facetype == '1':
                    print('theme.face.%s.image =' % face, repr(pattern), file=settings)
            elif key == 'imagefile':
                imagefile = value
                if facetype == '2':
                    print('theme.face.%s.image =' % face, repr(imagefile), file=settings)
            elif key == 'imagemode':
                imagemode = 'tiled' if value != '1' else 'mosaic'
                if facetype == '2':
                    print('theme.face.%s.mode =' % face, repr(imagemode), file=settings)
            
def main():
    if len(sys.argv) != 2:
        sys.exit(1)
    gconf_0_5_to_settings_1_0(sys.argv[1])
    
    
if __name__ == '__main__':
    main()


