#!/usr/bin/env python 
'''
Copyright (C) 2009 David Gibson <david@gibson.dropbear.id.au>

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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
'''
import sys
sys.path.append('/usr/share/inkscape/extensions')
import inkex
import simpletransform

def elem_equal(node1, node2, ignore_transform = True):
#    print >>sys.stderr, "elem_equal(%s, %s)" % (node1.get('id'), node2.get('id'))
    if node1.tag != node2.tag:
#        print >>sys.stderr, "Tag mismatch"
        return False
    if node1.text and node1.text.strip():
        print >>sys.stderr, "Non trivial text on %s" % (node1.get('id'))
    if node2.text and node2.text.strip():
        print >>sys.stderr, "Non trivial text on %s" % (node2.get('id'))

    if node1.tail and node1.tail.strip():
        print >>sys.stderr, "Non trivial tail on %s" % (node1.get('id'))
    if node2.tail and node2.tail.strip():
        print >>sys.stderr, "Non trivial tail on %s" % (node2.get('id'))

    for key, val1 in node1.items():
        if key == 'id':
            continue
        if key == 'transform' and ignore_transform:
            continue
        val2 = node2.get(key)
        if val2 == None:
#            print >>sys.stderr, "attrib %s L-mismatch" % key
            return False
        if val1 != val2:
#           print >>sys.stderr, "attrib %s val mismatch" % key
            return False
    for key in node2.keys():
        if key == 'id':
            continue
        if node1.get(key) == None:
#            print >>sys.stderr, "attrib %s R-mismatch" % key
            return False
    return True

def is_dupe(node1, node2, ignore_transform = True):
    if not elem_equal(node1, node2, ignore_transform):
        return False
    c1 = node1.getchildren()
    c2 = node2.getchildren()
    if len(c1) != len(c2):
#        print >>sys.stderr, "number of children mismatch"
        return False

    return all(map(is_dupe, c1, c2))

def invert_transf(mat):
    (a, b, c), (d, e, f) = mat
    det = a*e - b*d
    inv = [[e / det, -b / det, (b*f - e*c) / det],
           [-d / det, a / det, (d*c - a*f) / det]]
    return inv

def clonify_elem(id, node, baseid, basenode):
    base_transf = simpletransform.parseTransform(basenode.get('transform'))
    dup_transf = simpletransform.parseTransform(node.get('transform'))
    clone_transf = simpletransform.composeTransform(dup_transf,
                                                    invert_transf(base_transf))

    node.clear()
    node.tag = inkex.addNS('use','svg')
    node.set('transform', simpletransform.formatTransform(clone_transf))
    node.set('id', id)
    node.set(inkex.addNS('href','xlink'), '#' + baseid)

class Clonify(inkex.Effect):
    def __init__(self):
        inkex.Effect.__init__(self)
        self.OptionParser.add_option("--baseobject",
                                     action="store", type="string",
                                     dest="basesel", default=False,
                                     help="dummy")

    def effect(self):
        if self.options.basesel == "first":
            baseid = self.options.ids[0]
        elif self.options.basesel == "last":
            baseid = self.options.ids[-1]
        basenode = self.selected[baseid]
 #       print >>sys.stderr, "BASE: id=%s" % baseid

        for id, node in self.selected.iteritems():
            if id == baseid:
                continue
 #           print >>sys.stderr, "*** id=%s" % id
            if is_dupe(node, basenode):
                print >>sys.stderr, "%s is a dupe of %s" % (id, baseid)
                clonify_elem(id, node, baseid, basenode)
             
e = Clonify()
e.affect()
