#
# $Id: alcGObjects.py 648 2006-09-25 12:20:53Z trylon $
#
#    Copyright (C) 2005-2006  Alcugs pyprp Project Team
#    See the file AUTHORS for more info about the team
#
#    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
#
#    Please see the file COPYING for the full license.
#    Please see the file DISCLAIMER for more details, before doing nothing.
#

# Help library

try:
    import Blender
    try:
        from Blender import NMesh
    except Exception, detail:
        print detail
except ImportError:
    pass

import random, md5,math, binascii, struct

def distance(p1,p2):
    a1=p1[0]
    a2=p2[0]
    b1=p1[1]
    b2=p2[1]
    c1=p1[2]
    c2=p2[2]
    return math.sqrt(pow(a1-a2,2) + pow(b1-b2,2) + pow(c1-c2,2))


def addProp(object,name,val):
    try:
        p=object.getProperty(name)
        p.setData(val)
    except AttributeError:
        object.addProperty(name,val)


def getProp(object,property):
    try:
        p=object.getProperty(property)
        return(p.getData())
    except AttributeError:
        return None


def getMatrix(object):
    try:
        m=Blender.Mathutils.Matrix(object.getMatrix())
    except TypeError:
        i=object.getMatrix()
        m=Blender.Mathutils.Matrix([i[0][0],i[0][1],i[0][2],i[0][3]],
                                   [i[1][0],i[1][1],i[1][2],i[1][3]],
                                   [i[2][0],i[2][1],i[2][2],i[2][3]],
                                   [i[3][0],i[3][1],i[3][2],i[3][3]])
    return m


def alcHex2Ascii(what,size=4):
    if size==4:
        type=">I"
    elif size==2:
        type=">H"
    else:
        type=">B"
    a=struct.pack(type,what)
    return(binascii.hexlify(a).upper())


def alcAscii2Hex(name,size=4):
    if size==4:
        type=">I"
    elif size==2:
        type=">H"
    else:
        type=">B"

    while len(name)<size*2:
        name = "0" + name
    b=binascii.unhexlify(str(name))
    r, = struct.unpack(type,b)
    return(r)


def alcUniqueName(name,seed1=0,seed2=0,key="x"):
    if seed1==0 or seed2==0:
        w = str(name) + "%i" %int(random.random()*10000)
        rid=md5.new(w).hexdigest().upper()
        mname = str(name)[:10] + "%s%s" %(key[:1],rid[:6])
        return mname
    else:
        rid=((int(random.random()*10000)*100+setidx)*10 + i)
        mname = name[:10] + "%s%06X" %(key[:1],rid)
        return mname


def alcCreateLinkInPoint(name="LinkInPointDefault",where=None,page=0):
    obj = Blender.Object.New('Empty',name)
    scene = Blender.Scene.getCurrent()
    scene.link(obj)
    #obj.addProperty("name",name)
    obj.addProperty("alctype","swpoint")
    if page!=0:
        obj.addProperty("page_num",str(page))
    if where==None:
        obj.setLocation(Blender.Window.GetCursorPos())
    else:
        matrix=where.get()
        matrix.transpose()
        obj.setMatrix(matrix)
    obj.layers = [2,]
    obj.drawMode=9
    #Blender.Redraw()
    return obj


def alcCreateRegion(name="Region",where=None,page=0):
    tempname = alcUniqueName(name,0,0,'X')
    rgnsize = 4
    rgnoffset = 0 - (rgnsize/2)
    obj = alcCreateBox(tempname,rgnsize,rgnoffset,rgnoffset,rgnoffset)
    obj.addProperty("alctype","region")
    obj.addProperty("prpregion","unknown")

    if page!=0:
        obj.addProperty("page_num",str(page))
    if where==None:
        obj.setLocation(Blender.Window.GetCursorPos())
    else:
        matrix=where.get()
        matrix.transpose()
        obj.setMatrix(matrix)
    obj.layers = [2,]
    obj.drawType = 2
    #Blender.Redraw()
    return obj


def alcCreatePanicLnkRegion(name="PanicLnk",where=None,page=0):
    obj = alcCreateRegion(name,where,page)
    p = obj.getProperty("prpregion")
    p.setData("paniclnkrgn")
    return obj

def alcCreateFootstepRegion(name="FootStep",where=None,page=0):
    obj = alcCreateRegion(name,where,page)
    p = obj.getProperty("prpregion")
    p.setData("footsteprgn")
    obj.addProperty("footstepsound",int(0))
    return obj

def alcCreateClickableRegion(where=None,page=0):
    obj = alcCreateRegion("ClickableRegion",where,page)
    p = obj.getProperty("prpregion")
    p.setData("clickregion")
    return obj

def alcCreateCameraRegion(name="CameraRgn",where=None,page=0):
    obj = alcCreateRegion(name,where,page)
    p = obj.getProperty("prpregion")
    p.setData("camerargn")
    obj.addProperty("camera","")
    obj.addProperty("setDefCam","false")
    return obj

def alcCreateSwimRegion(name="SwimDetRgn",where=None,page=0):
    obj = alcCreateRegion(name,where,page)
    p = obj.getProperty("prpregion")
    p.setData("swimrgn")
    return obj

def alcCreateSwimSurface(name="SwimSfc",where=None,page=0):
    tempname = alcUniqueName(name,0,0,'sfc')
    rgnsize = 4
    rgnoffset = 0 - (rgnsize/2)
    obj = alcCreatePlane(tempname,rgnsize,rgnoffset,rgnoffset,0)
    scene = Blender.Scene.getCurrent()
    #scene.link(obj)
    obj.addProperty("name",tempname)
    obj.addProperty("alctype","region")
    obj.addProperty("prpregion","swimplainsfc")

    if page!=0:
        obj.addProperty("page_num",str(page))
    if where==None:
        obj.setLocation(Blender.Window.GetCursorPos())
    else:
        matrix=where.get()
        matrix.transpose()
        obj.setMatrix(matrix)
    obj.layers = [2,]
    obj.drawType = 2
    #Blender.Redraw()
    return obj


def alcCreateMesh(name,vertexs,faces):
    obj = NMesh.New(name)
    for e in range(len(vertexs)):
        vert = NMesh.Vert(vertexs[e][0],vertexs[e][1],vertexs[e][2])
        obj.verts.append(vert)
    for f in faces:
        face = NMesh.Face()
        for v in f:
            face.append(obj.verts[v])
        obj.faces.append(face)
    sobj=NMesh.PutRaw(obj,name,1)
    sobj.setName(name)
    return sobj


def alcCreateBox(name,size,x=0,y=0,z=0):
    obj = NMesh.New(name)
    vert0 = NMesh.Vert(x,y,z)
    obj.verts.append(vert0)
    vert1 = NMesh.Vert(size+x,y,z)
    obj.verts.append(vert1)
    vert2 = NMesh.Vert(x,size+y,z)
    obj.verts.append(vert2)
    vert3 = NMesh.Vert(x,y,size+z)
    obj.verts.append(vert3)
    vert4 = NMesh.Vert(size+x,size+y,size+z)
    obj.verts.append(vert4)
    vert5 = NMesh.Vert(size+x,size+y,z)
    obj.verts.append(vert5)
    vert6 = NMesh.Vert(size+x,y,size+z)
    obj.verts.append(vert6)
    vert7 = NMesh.Vert(x,size+y,size+z)
    obj.verts.append(vert7)
    face = NMesh.Face()
    face.append(vert0)
    face.append(vert2)
    face.append(vert5)
    face.append(vert1)
    obj.faces.append(face)
    face = NMesh.Face()
    face.append(vert5)
    face.append(vert2)
    face.append(vert7)
    face.append(vert4)
    obj.faces.append(face)
    face = NMesh.Face()
    face.append(vert1)
    face.append(vert5)
    face.append(vert4)
    face.append(vert6)
    obj.faces.append(face)
    face = NMesh.Face()
    face.append(vert0)
    face.append(vert1)
    face.append(vert6)
    face.append(vert3)
    obj.faces.append(face)
    face = NMesh.Face()
    face.append(vert3)
    face.append(vert6)
    face.append(vert4)
    face.append(vert7)
    obj.faces.append(face)
    face = NMesh.Face()
    face.append(vert0)
    face.append(vert3)
    face.append(vert7)
    face.append(vert2)
    obj.faces.append(face)
    sobj=NMesh.PutRaw(obj)
    sobj.setName(name)
    return sobj


def alcCreatePlane(name,size,x=0,y=0,z=0):
    obj = NMesh.New(name)
    vert0 = NMesh.Vert(x,y,z)
    obj.verts.append(vert0)
    vert1 = NMesh.Vert(size+x,y,z)
    obj.verts.append(vert1)
    vert3 = NMesh.Vert(x,size+y,z)
    obj.verts.append(vert3)
    vert2 = NMesh.Vert(size+x,size+y,z)
    obj.verts.append(vert2)
    face = NMesh.Face()
    face.append(vert0)
    face.append(vert1)
    face.append(vert2)
    face.append(vert3)
    obj.faces.append(face)
    sobj=NMesh.PutRaw(obj,name,1)
    sobj.setName(name)
    return sobj


def alcFindBlenderText(name):
    try:
        out=Blender.Text.Get(name)
    except NameError:
        out=Blender.Text.New(name)
    return out


def alcCreateClimbRegion(name="ClimbRgn",where=None,page=0):
    obj = alcCreateRegion("ClickableRegion",where,page)
    p = obj.getProperty("prpregion")
    p.setData("climbregion")

    obj.addProperty("bottomFlag","00")
    obj.addProperty("climbOffset",int(0))
    obj.addProperty("climbHeight",int(0))
    return obj
    
def deldefaultproperty(obj,propertyname,defaultvalue):
    try:
        p=obj.getProperty(propertyname)
        if(p.getData() == defaultvalue):
            obj.removeProperty(p)
    except AttributeError:
        print "Error removing %s property" % propertyname
        
def getFloatPropertyOrDefault(obj,propertyname,defaultvalue):
    try:
        p=obj.getProperty(propertyname)
        if(p.type == "FLOAT"):
            var=float(p.getData())
        else:
            var=defaultvalue
    except AttributeError:
        var=defaultvalue
    return var

def getHexPropertyOrDefault(obj,propertyname,bytesize,defaultvalue):
    try:
        p=obj.getProperty(propertyname)
        if(p.type == "STRING"):
            var=alcAscii2Hex(str(p.getData()),bytesize)
        else:
            var=defaultvalue
    except AttributeError:
        var=defaultvalue
        pass
    return var

def getTextPropertyOrDefault(obj,propertyname,defaultvalue):
    try:
        p=obj.getProperty(propertyname)
        if(p.type == "STRING"):
            var=str(p.getData())
        else:
            var=defaultvalue
    except AttributeError:
        var=defaultvalue
        pass
    return var

def getStrIntPropertyOrDefault(obj,propertyname,defaultvalue):
    try:
        p=obj.getProperty(propertyname)
        if(p.type == "STRING"):
            var=int(p.getData())
        else:
            var=defaultvalue
    except AttributeError:
        var=defaultvalue
        pass
    return var

def getIntPropertyOrDefault(obj,propertyname,defaultvalue):
    try:
        p=obj.getProperty(propertyname)
        if(p.type == "INT"):
            var=int(p.getData())
        else:
            var=defaultvalue
    except AttributeError:
        var=defaultvalue
        pass
    return var