#!/usr/bin/python
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------------
# Xcode 4 template generator for cocos2d project
# (c) 2011 Ricardo Quesada
#
# LICENSE: Dual License: MIT & GNU GPL v2 Whatever suits you best.
#
# Given a directory, it generates the "Definitions" and "Nodes" elements
#
# Format taken from: http://blog.boreal-kiss.net/2011/03/11/a-minimal-project-template-for-xcode-4/
# ----------------------------------------------------------------------------
'''
Xcode 4 template generator
'''

__docformat__ = 'restructuredtext'

_template_open_body = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- FILE AUTOGENERATED BY cocos2d/tools/template_generator.py DO NOT EDIT -->
<plist version="1.0">
<dict>
	<key>Description</key>
	<string>This is a template description.</string>
	<key>Identifier</key>
	<string>com.cocos2d-v2.%s</string>
	<key>Kind</key>
	<string>Xcode.Xcode3.ProjectTemplateUnitKind</string>"""

_template_close_body = "</dict>\n</plist>"

_template_header_path= """<key>Targets</key>
	<array>
		<dict>
			<key>SharedSettings</key>
			<dict>
				<key>HEADER_SEARCH_PATHS</key>
				<string>%s</string>
			</dict>
		</dict>
	</array>"""

_template_user_header_path= """<key>Targets</key>
	<array>
		<dict>
			<key>SharedSettings</key>
			<dict>
				<key>ALWAYS_SEARCH_USER_PATHS</key>
				<string>YES</string>
				<key>USER_HEADER_SEARCH_PATHS</key>
				<string>%s</string>
			</dict>
		</dict>
	</array>"""

_template_ancestor = """    <key>Ancestors</key>
	<array>
		<string>%s</string>
	</array>"""

# python
import sys
import os
import getopt
import glob

class Xcode4Template(object):
    def __init__(self, directory, group=0, identifier="XXX", header_path=None, user_header_path=None, ancestor=None):
        self.directory = directory
        self.files_to_include = []
        self.wildcard = '*'
        self.ignore_extensions = ['h','txt','html','patch','cmake', 'py', 'markdown', 'md', 'graffle', 'sh', 'ini', 'bridgesupport', 'tbl', 'msg']
        self.ignore_directories = ['docs', 'html']
        self.group_start_index = group  # eg: if 1 then libs/cocos2d/support -> ["cocos2d", "support"] ignoring "libs"
        self.output = []
        self.identifier = identifier
        self.header_path = header_path
        self.user_header_path = user_header_path
        self.ancestor = ancestor

    def scandirs(self, path):
        for currentFile in glob.glob(os.path.join(path, self.wildcard)):
            if os.path.isdir(currentFile):
                self.scandirs(currentFile)
            else:
                self.files_to_include.append(currentFile)

    #
    # append the definitions
    #
    def append_definition(self, output_body, path, group, dont_index):
        output_body.append("\t\t<key>%s</key>" % path)

        output_body.append("\t\t<dict>")
        if group:
            output_body.append("\t\t\t<key>Group</key>")
            output_body.append("\t\t\t<array>")
            for g in group:
                output_body.append("\t\t\t\t<string>%s</string>" % g)
            output_body.append("\t\t\t</array>")


        output_body.append("\t\t\t<key>Path</key>\n\t\t\t<string>%s</string>" % path)

        if dont_index:
            output_body.append("\t\t\t<key>TargetIndices</key>\n\t\t\t<array/>")

        output_body.append("\t\t</dict>")

    #
    # Generate the "Definitions" section
    #
    def generate_definitions(self):
        output_header = "\t<key>Definitions</key>"
        output_dict_open = "\t<dict>"
        output_dict_close = "\t</dict>"

        output_body = []
        for path in self.files_to_include:

            # group name
            group = []
            # obtain group name from directory
            dirs = os.path.dirname(path)

            lastdir = dirs.split(os.path.sep)[-1]
            if lastdir in self.ignore_directories:
                sys.stderr.write('Ignoring definition: "%s" because it is in directory: "%s"\n' % (os.path.basename(path), lastdir))
                continue

            group = dirs.split('/')

            group = group[self.group_start_index:]

            # get the extension
            filename = os.path.basename(path)
            name_extension= filename.split('.')
            extension = None
            if len(name_extension) == 2:
                extension = name_extension[1]

            self.append_definition(output_body, path, group, extension in self.ignore_extensions)

        self.output.append(output_header)
        self.output.append(output_dict_open)
        self.output.append("\n".join(output_body))
        self.output.append(output_dict_close)

    # 
    # Generates the "Nodes" section
    #
    def generate_nodes(self):
        output_header = "\t<key>Nodes</key>"
        output_open = "\t<array>"
        output_close = "\t</array>"

        output_body = []

        for path in self.files_to_include:

            lastdir = os.path.dirname(path).split(os.path.sep)[-1]
            if lastdir in self.ignore_directories:
                sys.stderr.write('Ignoring node: "%s" because it is in directory: "%s"\n' % (os.path.basename(path), lastdir))
                continue

            output_body.append("\t\t<string>%s</string>" % path)

        self.output.append(output_header)
        self.output.append(output_open)
        self.output.append("\n".join(output_body))
        self.output.append(output_close)


    #
    # Generate ancestors
    #
    def generate_ancestor(self):
        if self.ancestor:
            self.output.append(_template_ancestor % self.ancestor)

    #
    # Generates the include directory
    #
    def generate_header_path(self):
        if self.header_path:
            self.output.append(_template_header_path % self.header_path)

        if self.user_header_path:
            self.output.append(_template_user_header_path % self.user_header_path)
      
    #
    # Generates the plist. Send it to to stdout
    #
    def generate_xml(self):
        self.output.append(_template_open_body % self.identifier)
        self.generate_ancestor()
        self.generate_definitions()
        self.generate_nodes()
        self.generate_header_path()
        self.output.append(_template_close_body)

        print "\n".join(self.output)

    def generate(self):
        self.scandirs(self.directory)
        self.generate_xml()

def help():
    print "%s v1.1 - An utility to generate Xcode 4 templates" % sys.argv[0]
    print "Usage:"
    print "-g --group\t\tdirectory_used_as_starting_group (if 1, then 'libs/cocos2d/Support/' -> ['cocos2d','Support'] ignoring 'libs')"
    print "-i --identifier\t\tidentifier (Xcode4 template identifier)"
    print "-a --ancestor\t\tancestor identifier. Default: none"
    print "--header-path\t\theader search path"
    print "--user-header-path\tuser header search path"
    print "directory_to_parse"
    print "\nExample:"
    print "\t%s -i kazmathlib --header-path ___PACKAGENAME___/libs/kazmath/include libs" % sys.argv[0]
    print "\t%s -i cocos2dlib libs" % sys.argv[0]
    sys.exit(-1)

if __name__ == "__main__":
    if len(sys.argv) == 1:
        help()

    directory = None
    group = 0
    identifier = None
    header_path= None
    user_header_path= None
    ancestor = None
    argv = sys.argv[1:]
    try:                                
        opts, args = getopt.getopt(argv, "a:g:i:", ["ancestor=","group=","identifier=","header-path=", "user-header-path="])

        if len(args) == 0:
            help()

        for opt, arg in opts:
            if opt in ("-g","--group"):
                group = arg
            if opt in ("-i","--identifier"):
                identifier = arg
            if opt in  ["--header-path"]:
                header_path= arg
            if opt in  ["--user-header-path"]:
                user_header_path= arg
            if opt in  ("-a", "--ancestor"):
                ancestor = arg
    except getopt.GetoptError,e:
        print e

    directory = args[0]

    if directory == None:
        help()

    gen = Xcode4Template(directory=directory, group=int(group), identifier=identifier, header_path=header_path, user_header_path=user_header_path, ancestor=ancestor)
    gen.generate()

