#!/usr/bin/python
import os, os.path
import sys
from XKit import xutils, xorgparser
import time
import shutil
import getopt

proprietary = 'nvidia'
free_alternative = 'nv'
source = '/etc/X11/xorg.conf'
destination = source

class DriverHandler(object):
    
    def changeDriver(self, proprietary_driver=proprietary, free_driver=free_alternative, xorg_source=source, xorg_destination=destination):
        '''
        Replace a free driver with it proprietary alternative in all Device sections.
        '''
        
        if os.path.exists(xorg_destination):
            #make a backup of the xorg.conf
            backup = xorg_destination + "_xconfig." + time.strftime("%Y%m%d%H%M%S")
            try:
                shutil.copyfile(xorg_destination, backup)
            except IOError:
                print 'Error: you don\'t seem to have the permission to modify your %s.\nTry using "sudo"' % (xorg_destination)
                sys.exit(1)
        
        try:
            a = xutils.XUtils(xorg_source)
        except(IOError, xorgparser.ParseException):#if xorg.conf is missing or broken
            a = xutils.XUtils()#start from scratch
        
        # the number of Device sections in the xorg.conf
        devicelen = len(a.globaldict['Device'])
        # the number of Screen sections in the xorg.conf
        screenlen = len(a.globaldict['Screen'])
        
        device = 0
        screen = 0
        
        if devicelen == 0:#create a minimal xorg.conf
            device = a.makeSection('Device', 'Configured Video Device')
        
        if screenlen == 0:
            screen = a.makeSection('Screen', identifier='Configured Screen Device')
            #a.addReference('Screen', 'Device', 'Configured Video Device', position=screen)
        
        # set DefaultDepth to 24; X.org does not work otherwise
        a.addOption('Screen', 'DefaultDepth', '24', position=None, prefix='')
        
        # set the driver to nvidia in all Device sections
        a.setDriver('Device', proprietary_driver, None)
        
        # make sure that RGB path is not in the xorg.conf otherwise xorg will crash
        it = 0
        for section in a.globaldict['Files']:
            try:
                a.removeOption('Files', 'RgbPath', position=it)
            except (xorgparser.OptionException):
                pass
            it += 1
        
        # write the changes to the destination file
        a.writeFile(xorg_destination)
        return True


def usage():
    instructionsList = ['The only accepted parameters are:'
    '\n  --output-xconfig=destination', '\twrite to a file other than /etc/X11/xorg.conf'
    
    '\n  --help', '\t\t\tdisplays this page'
    ]
    print ''.join(instructionsList)

def main():
    err = 'Error: parameters not recognised'
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'ho:v', ['help', 'output-xconfig=', 'verbose'])
    except getopt.GetoptError, err:
        # print help information and exit:
        print str(err) # will print something like 'option -a not recognized'
        usage()
        sys.exit(2)
    newDestination = None
    verbose = None
    for o, a in opts:
        if o in ('-v', '--verbose'):
            verbose = True
        elif o in ('-o', '--output-xconfig'):
            newDestination = a
        elif o in ('-h', '--help'):
            usage()
            sys.exit()
        else:
            assert False, 'unhandled option'
    driver = DriverHandler()
#    print 'New Destination is', newDestination
    if newDestination:
        driver.changeDriver(xorg_destination=newDestination)
    else:
        driver.changeDriver()


if __name__ == '__main__':
    main()
