#!/usr/bin/python
# dtd_parser.py - DTD structure parser
#
# Copyright (C) 2012 The ChromiumOS Authors.  All rights reserved.
#
# 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; version 2 of the License
#
# 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, write to the Free Software
# Foundation, Inc.
#

'''
DTD string parser/generator.

Detailed timing descriptor (DTD) is an 18 byte array describing video mode
(screen resolution, display properties, etc.) in EDID and used by Intel Option
ROM. Option ROM can support multiple video modes, specific mode is picked by
the BIOS through the appropriate Option ROM callback function.

This program allows to interpret the 18 byte hex DTD dump, and/or modify
certain values and generate a new DTD.
'''

import sys

#
# The DTD array format description can be found in
# http://en.wikipedia.org/wiki/Extended_display_identification_data, (see the
# EDID Detailed Timing Descriptor section).
#
# The below dictionary describes how different DTD parameters are laid out in
# the array. Note that many parameters span multiple bit fields in the DTD.
#
# The keys in the dictionary are stings (field names), the values are tuples
# of either numbers or tri-tuples. If the element of the tuple is a number, it
# is the offset in DTD, and the entire byte is used in this field. If the
# element is a tri-tuple, its components are (DTD offset, bit shift, field
# width).
#
# The partial values are extracted from the DTD fields and concatenated
# together to form actual parameter value.
#

dtd_descriptor  = {
    'dclck' : (1, 0),
    'hor_active' : ((4, 4, 4), 2),
    'hor_blank' : ((4, 0, 4), 3),
    'vert_act' : ((7, 4, 4), 5),
    'vert_blank' : ((7, 0, 4), 6),
    'hsync_offset' : ((11, 6, 2), 8),
    'hsync_pulse_width' : ((11, 4, 2), 9),
    'vsync_offset' : ((11, 2, 2), (10, 4, 4)),
    'vsync_pulse_width' : ((11, 0, 2), (10, 0, 4)),
    'hor_image_size' : ((14, 4, 4), 12),
    'vert_image_size' : ((14, 0, 4), 13),
    'hor_border' : (15,),
    'vert_border' : (16,),
    'interlaced' : ((17, 7, 1),),
    'reserved' : ((17, 5, 2), (17, 0, 1)),
    'digital_separate' : ((17, 3, 2),),
    'vert_polarity' : ((17, 2, 1),),
    'hor_polarity' : ((17, 1, 1),),
    }

PREFIX = 'attr_'

class DTD(object):
    '''An object containing all DTD information.

    The attributes are created dynamically when the input DTD string is
    parsed. For each element of the above dictionary two attributes are added:

    'attr_<param>' to hold the actual parameter value
    'max_attr_<param>' to hold the maximum allowed value for this parameter.
    '''

    def __init__(self):
        for name in dtd_descriptor:
            setattr(self, PREFIX + name, 0)

    def init(self, sarray):
        '''Initialize the object with values from a DTD array.

        Inputs:

        sarray: a string, an array of ASCII hex representations of the 18 DTD
                bytes.

        Raises: implicitly raises ValueError or IndexError exceptions in case
                the input string has less than 18 elements, or some of the
                elements can not be converted to integer.
        '''

        harray = [int(x, 16) for x in sarray]
        for name, desc in dtd_descriptor.iteritems():
            attr_value = 0
            total_width = 0
            for tup in desc:
                if isinstance(tup, tuple):
                    offset, shift, width = tup
                else:
                    offset, shift, width = tup, 0, 8

                mask = (1 << width) - 1
                attr_value = (attr_value << width) + (
                    (harray[offset] >> shift) & mask)
                total_width += width
            setattr(self, PREFIX + name, attr_value)
            setattr(self, 'max_' + PREFIX + name, (1 << total_width) - 1)

    def __str__(self):
        text = []
        for name in sorted(dtd_descriptor.keys()):
            text.append('%20s: %d' % (name, getattr(self, PREFIX + name)))
        return '\n'.join(text)

    def inhex(self):
        '''Generate contents of the DTD as a 18 byte ASCII hex array.'''

        result = [0] * 18
        for name, desc in dtd_descriptor.iteritems():
            attr_value = getattr(self, PREFIX + name)
            rdesc = list(desc)
            rdesc.reverse()
            for tup in rdesc:
                if isinstance(tup, tuple):
                    offset, shift, width = tup
                else:
                    offset, shift, width = tup, 0, 8

                mask = (1 << width) - 1
                value = attr_value & mask
                attr_value = attr_value >> width
                result[offset] = (result[offset] & ~(
                        mask << shift)) | (value << shift)

        return ' '.join('%2.2x' % x for x in result)

    def handle_input(self, name):
        '''Get user input and set a new parameter value if required.

        Display the parameter name, its current value, and prompt user for a
        new value.

        If the user enters a dot, stop processing (return True).

        Empty user input means that this parameter does not have to change,
        but the next parameter should be prompted.

        If input is non-empty, it is interpreted as a hex number, checked if
        it fits the parameter and the new parameter value is set if checks
        pass.

        Inputs:

        name - a string, parameter name, a key in dtd_descriptor

        Returns:

        Boolean, True meaning no more field are required to be modified, False
                 meaning that more field mods need to be prompted..
        '''

        param = PREFIX + name
        vmax = getattr(self, 'max_' + param)
        new_value = raw_input('%s : %d '  % (name, getattr(self, param)))
        if new_value == '':
            return False
        if new_value == '.':
            return True
        new_int = int(new_value)
        if new_int > vmax:
            print '%s exceeds maximum for %s (%d)' % (new_value, name, vmax)
        else:
            setattr(self, param, new_int)
        return False

def main(args):
    if args[0] == '-m':
        modify = True
        base = 1
    else:
        modify = False
        base = 0

    d = DTD()
    d.init(args[base:])
    if modify:
        for line in str(d).splitlines():
            if d.handle_input(line.split(':')[0].strip()):
                break
    print d
    if modify:
        print d.inhex()


if __name__ == '__main__':
    try:
        main(sys.argv[1:])
    except (ValueError, IndexError):
        print """
A string of 18 byte values in hex is required.
'-m' preceding the string will allow setting new parameter values.
"""
        sys.exit(1)
