import bpy
import json
import os
import subprocess
import time
import shutil

#import export_code

bl_info = {
    "name": "AGK Exporter",
    "author": "Your Name",
    "version": (1, 0),
    "blender": (2, 79, 0),
    "location": "View3D > Tool Shelf > AGK",
    "description": "Export AGK code and AGK load script",
    "category": "Development"
}

def code():
    # your code here
    print("Exporting AGK code...")




class ExportAGKLoadScriptOperator(bpy.types.Operator):
    bl_idname = "object.export_agk_load_script"
    bl_label = "Test/Play"

    def execute(self, context):
        json_export()
        return {'FINISHED'}





class AGKPanel(bpy.types.Panel):
    bl_idname = "OBJECT_PT_agk_panel"
    bl_label = "AGK"
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_category = "AGK"

    def draw(self, context):
        layout = self.layout
        layout.operator("object.export_agk_code")
        layout.operator("object.export_agk_load_script")
        layout.operator("object.test_play")
        layout.label(text="WorkSpace Project Name to save ")
        layout.label(text="will overwrite Files if they exist")

        col = self.layout.column(align = True)
        col.prop(context.scene, "my_string_prop")


    
    
    
    
    
def json_export():

    home_dir = os.path.expanduser("~")
    data=[]

    newdata=""
    # Loop through each selected object and get its rotation, position, and texture information
    projectName=bpy.context.scene.my_string_prop
    filepath = os.path.join(home_dir , "Desktop")
    workspace= os.path.join(filepath, "Agk_WorkSpace")
    Project=os.path.join(workspace, projectName)
    filename="import.lls"
    
    if not os.path.exists(workspace):
        os.makedirs(workspace)

    if not os.path.exists(Project):
        os.makedirs(Project)
        
    objPath=os.path.join(Project,"media/objects")
    if not os.path.exists(objPath):
        os.makedirs(objPath)
    texPath=os.path.join(Project,"media/textures")
    if not os.path.exists(texPath):
        os.makedirs(texPath)
        
    texPath2=os.path.join(Project,"media/textures/bulk")
    if not os.path.exists(texPath2):
        os.makedirs(texPath2)
        

    # Iterate over all the objects in the scene
    for obj in bpy.context.scene.objects:
        data.append("\n:Type:"+obj.type+":")
        data.append(":Name:"+obj.name+":")
        data.append("//Rotation")
        data.append(":x:"+str(obj.rotation_euler[0])+":")
        data.append(":y:"+str(obj.rotation_euler[1])+":")
        data.append(":z:"+str(obj.rotation_euler[2])+":")
        data.append("//Position")
        data.append(":x:"+str(obj.location[0])+":")
        data.append(":y:"+str(obj.location[1])+":")
        data.append(":z:"+str(obj.location[2])+":")
        if obj.type=="LAMP":
            l=obj.data.color
            data.append(":"+str(int(l[0]*255))+":"+str(int(l[1]*255))+":"+str(int(l[2]*255))+":")
            data.append(obj.data.distance)
        # Iterate over all of the current object's material slots
        for m in obj.material_slots:
            if m.material:
                c=m.material.diffuse_color
                data.append("//Material Color RGB")
                data.append(":"+str(int(c[0]*255))+":"+str(int(c[1]*255))+":"+str(int(c[2]*255))+":")
                
                # Iterate over all the current material's texture slots
                for t in m.material.texture_slots:
                    # If this is an image texture, with an active image append its name to the list
                    if t and t.texture.type == 'IMAGE' and t.texture.image:
                        data.append(":Texture:" +t.texture.image.name +":"+m.name+":")
                        #data.append(t.texture.name)
                        projectName=bpy.context.scene.my_string_prop
                        filepath = os.path.join(home_dir , "Desktop")
                        workspace= os.path.join(filepath, "Agk_WorkSpace")
                        Project=os.path.join(workspace, projectName)
                        shutil.copy(t.texture.image.filepath,workspace+"\\"+projectName+"\\media\\textures\\bulk")
                        
                        
        data.append("//END")
    data.append("//scene")
    scene=bpy.context.scene.world
    col=scene.ambient_color
    data.append(":"+str(int(col[0]*255))+":"+str(int(col[1]*255))+":"+str(int(col[2]*255))+":")
    # Convert the list of dictionaries to JSON format
    
    

    
    for i in data:
        newdata=newdata+str(i)+"\n"
        filepath2 = os.path.join(Project, filename)
    with open(filepath2, "w") as f:
        f.write(newdata)
    
    ##################EXPORT#######################################################
        # Set the filepath and filename for the FBX export
    directory = objPath+"/"

    # Loop through all objects in the scene
    for obj in bpy.context.scene.objects:

        # Select the object
        bpy.ops.object.select_all(action='DESELECT')
       
        obj.select=True
        # Set the output filepath for the FBX file
        filepath = directory + obj.name + ".fbx"
       # bpy.ops.object.active=obj
        #bpy.context.scene.objects.active=obj
        # Export the selected object to FBX
        if obj.type=="MESH":
            bpy.ops.export_scene.fbx(filepath=filepath, check_existing=False,object_types={'ARMATURE', 'CAMERA', 'LAMP', 'MESH'}, filter_glob='*.fbx', use_selection=True, global_scale=1.0, apply_unit_scale=True, 
            apply_scale_options='FBX_SCALE_NONE',
             use_mesh_modifiers_render=True, mesh_smooth_type='FACE', 
            use_mesh_edges=True,  use_custom_props=False, 
            add_leaf_bones=True, primary_bone_axis='Y', secondary_bone_axis='X', use_armature_deform_only=False, 
            armature_nodetype='NULL', bake_anim=True, bake_anim_use_all_bones=True, bake_anim_use_nla_strips=True, 
            bake_anim_use_all_actions=True, bake_anim_force_startend_keying=True, bake_anim_step=1.0, 
            bake_anim_simplify_factor=1.0, path_mode='AUTO', batch_mode='OFF', 
            use_batch_own_dir=True, axis_forward='-Z', axis_up='Y')
        #obj.deselect=True
       
            
        
        
        
    
    agklist="""[apk_settings]
alias=
app_new_icon_path=
app_icon_path=
notif_icon_path=
app_name=
app_type=0
game_circle_api_key=
keystore_path=
orientation=0
output_path=
ouya_icon_path=
package_name=
permission_flags=7
play_app_id=
admob_app_id=
snapchat_client_id=
sdk_version=1
version_name=
version_number=0
firebase_config_path=
url_scheme=
deep_link=
arcore=0

[ipa_settings]
app_name=
app_icon_path=
build_number=
version_number=
device_type=0
facebook_id=
orientation=0
output_path=
uses_ads=0
url_scheme=
deep_link=
admob_app_id=
snapchat_client_id=
splash_logo=
firebase_config_path=
splash_color=
prov_profile_path=

[html5_settings]
commands_used=0
dynamic_memory=0
output_path=

[projectfiles]
FILE_0=main.agc;-1
FILE_1=Import.agc;-1

[files]
FILE_NAME_0=0;main.agc;13;0
FILE_NAME_1=1;Import.agc;13;1


[watchvariables]"""
              
    oldprojectName= projectName
    projectName=projectName+".agk"
    filepath2 = os.path.join(Project,projectName)
    with open(filepath2, "w") as f:
        f.write(agklist)       
        
        
        
        
    mainList="""
SetErrorMode(2)

// set window properties
SetWindowTitle( "test" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window

// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 )
setcameraposition(1,0,1,-2)
SetCameraRange(1,0.01,100)
SetCameraLookAt(1,1,1,0,0)
SetGenerateMipmaps(1)
SetSunActive(1)
#include "Import.agc"
runImport()

do
	Camera_controls()
    Sync()
loop
"""
    
    filepath3 = os.path.join(Project,"main.agc")
    if not os.path.exists(filepath3):
        with open(filepath3, "w") as f:
            f.write(mainList)
        
    importList="""

function runImport()
    global obj as objectType[]
    global LoadedImages as loadedimagestype []
    global Dir as dirtype []
    global TempDir as dirtype
	global path as string
	global light as lighttype []
	path="raw:"+getreadpath()+"media/"
	FileDiscovery("textures")
  loadLevel()
  t as lighttype
  t.name="null"
  light.insert(t)
Endfunction

type Loadedimagestype
	ImageName as string
	ImageID as integer
endtype

type ObjectType
	Name as string
	ID as integer
	rot as vectype
	pos as vectype
	textname as string[]
	meshtexture as meshtexturetype
	textid as integer[]
endtype

type meshtexturetype
	primary as integer []
	secondary as integer []
	normal as integer[]
endtype

type vectype
	 x as float
	 y as float
	 z as float
endtype

type lighttype
	number as integer
	kind as string
	name as string
	px as float
	py as float
	pz as float
	rx as float
	ry as float
	rz as float
	col as integer
	range as float
endtype





function loadLevel()
	setfolder("")
	read=OpenToRead("import.lls")
	setfolder("\media\objects")
	while FileEOF(read) = 0
		data$=readline(read)
		num=countstringtokens(data$,":")
		if num>0
			if GetStringToken(data$,":",1)="Type"
				if GetStringToken(data$,":",2)="MESH"
					 loadobj(read)
				endif
				if GetStringToken(data$,":",2)="LAMP" then loadLamp(read)
			endif
		endif
	endwhile
	`Textureobjects()
endfunction

function loadobj(read)
	setfolder("\media\objects")
	t as objecttype
	obj.insert(t)
	objid=obj.length
	data$=readline(read)
	obj[objid].name=getstringtoken(data$,":",2)
	obj[objid].id=loadobject(obj[objid].name+".fbx")
	setobjectscale(obj[objid].id,0.002,.002,.002)
	SetObjectCullMode(obj[objid].id,0)
	SetObjectCastShadow(obj[objid].id,1)
	SetObjectReceiveShadow(obj[objid].id,1)
	readline(read)
	data$=readline(read):obj[objid].rot.x=val(getstringtoken2(data$,":",2))
	data$=readline(read):obj[objid].rot.y=val(getstringtoken2(data$,":",2))
	data$=readline(read):obj[objid].rot.z=val(getstringtoken2(data$,":",2))
	data$=readline(read)
	data$=readline(read):obj[objid].pos.x=val(getstringtoken2(data$,":",2))
	data$=readline(read):obj[objid].pos.y=val(getstringtoken2(data$,":",2))
	data$=readline(read):obj[objid].pos.z=val(getstringtoken2(data$,":",2))
	
mesh=0
	for i = 0 to 10
		if data$="//END" then exitfunction
		data$=readline(read)
		if data$="//Material Color RGB"
			
			data$=readline(read)
			r=val(GetStringToken(data$,":",1))
			g=val(GetStringToken(data$,":",1))
			b=val(GetStringToken(data$,":",1))
			data$=readline(read)
		endif
		
			if GetStringToken(data$,":",1)="Texture"
				 name$=GetStringToken(data$,":",2)
				 str$=GetStringToken(data$,":",3)
				 if left(str$,6)="second" then load2=1
				 if left(str$,6)="normal" then load2=2
				 
				 if load2 >0
				 	 textid=LoadImages(name$)
				 endif
				 
				 if load2 < 1
				 	  textid=LoadImages(name$)
				  endif

				 if load2 < 1
				 	inc mesh,1
				 	obj[objid].textid.insert(textid)
					if GetObjectNumMeshes(obj[objid].id) < 1 
						 `setobjectimage(obj[objid].id,textid,0)
					else
						if mesh <=GetObjectNumMeshes(obj[objid].id) 
					 	 	SetObjectmeshImage(obj[objid].id,mesh,textid,0)
					 	 	obj[objid].meshtexture.primary.insert(textid)
					 	endif
					endif
				endif
				
				if load2=1
					if mesh =0  
						`SetObjectimage(obj[objid].id,textid,1)
						 load2=-1
					else
						if mesh <=GetObjectNumMeshes(obj[objid].id)
					 	 	SetObjectmeshimage(obj[objid].id,mesh,textid,1)
					 	 	obj[objid].meshtexture.secondary.insert(textid)
					 	endif
					endif
					load2=-1
				endif
				
				

				if load2=2
					if mesh =0  
						 `SetObjectNormalMap(obj[objid].id,textid)
					else
						if mesh <=GetObjectNumMeshes(obj[objid].id)
					 	 	SetObjectmeshnormalmap(obj[objid].id,mesh,textid)
					 	 	obj[objid].meshtexture.normal.insert(textid)
					 	endif
					endif
				endif
					load2=-1
				textid=-1
				name$=""
			str$=""
		endif
			
			

	next
endfunction

function loadlamp(read)
	global globalpointlights 
	name$=getstringtoken(readline(read),":",2)
	readline(read) //rotline
	data$=readline(read):rx#=val(getstringtoken2(data$,":",2))
	data$=readline(read):ry#=val(getstringtoken2(data$,":",2))
	data$=readline(read):rz#=val(getstringtoken2(data$,":",2))
	readline(read)//pos
	data$=readline(read):px#=val(getstringtoken2(data$,":",2))
	data$=readline(read):py#=val(getstringtoken2(data$,":",2))
	data$=readline(read):pz#=val(getstringtoken2(data$,":",2))
	col$=readline(read)
	c1=val(getstringtoken(col$,":",1))
	c2=val(getstringtoken(col$,":",2))
	c3=val(getstringtoken(col$,":",3))
	col=makecolor(c1,c2,c3)
	range#=round( val(readline(read)))
	
	
	//make sun
	if left(name$,3)="sun" 
		SetSunActive(1)
		SetSunColor(c1,c2,c3)
		SetSunDirection(px#,py#,pz#)
	endif

	if lower(left(name$,5))="point" or left(name$,4) ="Lamp"
		inc globalpointlights ,1
		num=globalpointlights 
		CreatePointLight(num,px#,py#,pz#,range#,c1,c2,c3)
		setpointlightmode(num,2)
		t as lighttype
		t.px=px#:t.py=py#:t.pz=pz#
		t.rx=rx#:t.ry=ry#:t.rx=rx#
		t.name=name$
		t.col=makecolor(c1,c2,c2)
		t.range=range#:t.kind="point"
		t.number=num
		light.insert(t)
	endif
	
endfunction 






function Camera_controls()
	y#=mousemovey()
	x#=Mousemovex()
	if GetRawMouseLeftstate()=1
	RotateCameralocalX(1,y#/2)
	RotateCameraglobaly(1,x#/2)
	endif
	if GetRawKeystate(87)=1
		MoveCameraLocalZ(1,.2)
	endif
	if GetRawKeystate(83)=1
		MoveCameraLocalZ(1,-.2)
	endif
endfunction

function MousemoveX()
    global OldMouseX#
    dx# = GetRawMouseX() - OldMouseX#
    OldMouseX# = GetRawMouseX()
endfunction dx#
 
 
 
function MousemoveY()
    global OldMouseY#
	dy# = GetRawMouseY() - OldMouseY#
    OldMouseY# = GetRawMouseY()
 endfunction dy#
remstart
function TextureObjects()
	SetObjectUVScale (object[i].id,1,1,1)
	setimagewrapu (Loadedimages[find].Imageid,1)
	setimagewrapv (Loadedimages[find].Imageid,1)
	if  found <=GetObjectNumMeshes(object[i].id)
		setobjectmeshimage(object[i].id,found,Loadedimages[find].Imageid,1)
	else
		if object[i].imageName.length =1
			parent=object[i].id
			image1=object[i].imageid[0]
			image2=object[i].imageid[1]
			ShaderFilter(parent,image1,image2)
		endif
	endif
lights()
endfunction
remend


	type dirtype
		DirName as string
		ImageName as string[]
		ImageID as integer[]
	endtype
	
	
	type TempDirtype
		DirName as string
	endtype
	




function FileDiscovery(directory$)
	ID=OpenRawFolder(path+directory$) //open media folder search for folders
	foldercount=GetRawFolderNumFolders(id) //get num of folders inside
	for i = 0 to Foldercount-1 //find names of folders 
		FolderName$=GetRawFolderFolderName(id,i)
		folder=i// folder= array id technically
		if len(foldername$)>0
			Tempdir.DirName=foldername$ //fill temp type
			Dir.insert(tempdir)//inserttemp into  dir type (folder name)
		endif
		newid=OpenRawFolder(path+directory$+"/"+foldername$)
		FindFiles(folder,newid)
	next
endfunction

function FindFiles(folder,id)//raw folder id
	FileCount=GetRawFolderNumFiles(id)
	For i = 0 to FileCount-1
		FileName$=GetRawFolderFileName(id,i)
		If len(FileName$)>0
			dir[folder].ImageName.insert(Filename$) //fill temp type
		endif
	next
endfunction

function LoadImages(FileName$)
	//loadimage into global image array dont load twice
	for i=0 to LoadedImages.length 
		
		if len(Loadedimages[i].ImageName)>-1
			if Loadedimages[i].imagename =Filename$
				found=i
			endif
		endif
	next
	
	`end
	`load image if not found
	if found=0
		if len(filename$)>1
			for directory=0 to dir.length 
				for image=0 to dir[directory].ImageName.length
					if dir[directory].ImageName[image]=filename$
						setfolder("/media")
						setfolder("Textures")
						setfolder(dir[directory].DirName)
						images=loadimage(filename$)
						t as loadedimagestype
						t.imagename=filename$
						t.imageid=images
						loadedimages.insert(t)
						found=LoadedImages.length
					endif
				next
			next
		endif
		else 
			images=loadedimages[found].ImageID
	endif
	
	
	
Endfunction images

    """
    filepath4 = os.path.join(Project,"Import.agc")
    if not os.path.exists(filepath4):
        with open(filepath4, "w") as f:
            f.write(importlist) 

    
    exe="D:\Program Files (x86)\The Game Creators\AppGameKit Studio\media\compiler\AGKCompiler.exe" 
    print("******************************************************************")
    print (exe)
    param1=Project
    print (param1)
    #param="-agk $("+Project+")"
    #subprocess.run([executable, param1, param2])
    subprocess.run([exe, param1])


    
    exe2=Project+"\\"+oldprojectName+".exe"
    print(exe2)
    subprocess.run([exe2,""])
        
        


            
        
        




































        
        
        
        
        
        
        
        
        
        
        
        
        
def register():
   # bpy.utils.register_class(ExportAGKCodeOperator)
    bpy.utils.register_class(ExportAGKLoadScriptOperator)
    #bpy.utils.register_class(TestPlayOperator)
    bpy.utils.register_class(AGKPanel)
    bpy.types.Scene.my_string_prop = bpy.props.StringProperty (name = "Name Of Project",description = "",default = "default")

def unregister():
    bpy.utils.unregister_class(ExportAGKCodeOperator)
    bpy.utils.unregister_class(ExportAGKLoadScriptOperator)
    bpy.utils.unregister_class(TestPlayOperator)
    bpy.utils.unregister_class(AGKPanel)
    del bpy.types.Scene.my_string_prop

if __name__ == "__main__":
    register()
