Format ElfObj64

include "../include/prog.h" "../include/prog.oh"
include "../include/throw.h" "../include/throw.oh"

vstr err="invalid gif file"

#win32 with _
importx "strlen" strlen

#import "swf_frames_pointer" swf_frames_pointer
#import "swf_sprite_frames_pointer" swf_sprite_frames_pointer

^import "button_mem" button_mem #full

import "stack_to_word_arg" stack_to_word_arg
^import "word_arg_to_stack" word_arg_to_stack 1
^import "struct_ids" struct_ids 2 #full
import "block_get_size" block_get_size
^import "block_get_mem" block_get_mem 1
import "free_sprite_id" free_sprite_id
import "freereset" freereset   #..x with no args
import "dtitles_conclude" dtitles_conclude
import "free_sprite_id_actions" free_sprite_id_actions
import "is_ainit" is_ainit
import "swf_mem_change_back" swf_mem_change_back
import "swf_actionblock_change_back" swf_actionblock_change_back
import "swf_actionblock_change" swf_actionblock_change #here id is verify first at swf_mem

import "ebase" ebase
#aftercallimport ebool

import "swf_mem" swf_mem
import "swf_mem_add" swf_mem_add
import "swf_actionblock_done" swf_actionblock_done
import "swf_tag_recordheader_entry" swf_tag_recordheader_entry
import "error" error
import "swf_shape_simple" swf_shape_simple
import "identifiers_get" identifiers_get

functionX swf_new(ss path,sd ?width,sd ?height,sd ?backgroundcolor,ss ?fps)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	callg swf_new_ex_local(path,width,height,backgroundcolor,fps,(flag_none))
endfunction

import "swf_button_base" swf_button_base
import "swf_text_initial_font_centered" swf_text_initial_font_centered
#id
functionX swf_button(sd ?width,sd ?height,sd ButtonData)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#data def_fill#1
#data def_line_h#1;#no pad
#data def_line#1

#data ov_fill#1;#no pad
#data ov_line_h#1
#data ov_line#1;#no pad

#data dn_fill#1;#no pad
#data dn_line_h#1
#data dn_line#1;#no pad

#data xcurve#1
#data ycurve#1;#no pad

#vstr text#1
#data font_id#1;data font_height#1;#no pad
#data font_vertical_offset#1;data font_color#1;#no pad

#vstr actions#1

#    const button_top_args=11*DWORD
#    call memcpy(#def_fill,ButtonData,(button_top_args))
#    add ButtonData (button_top_args);call memcpy(#text,ButtonData,:)
#    const button_font_args=4*DWORD
#    add ButtonData :;call memcpy(#font_id,ButtonData,(button_font_args))
#    add ButtonData (button_font_args);call memcpy(#actions,ButtonData,:)

#width                  is the button width
#height                 is the button height

#def_fill               is the ButtonStateUp RGBA fill color
#def_line_sz            line height in pixels
#def_line               is the line RGBA
#ov_fill                is the ButtonStateOver RGBA
#ov_line_sz             line height
#ov_line                RGBA
#dn_fill                is the ButtonStateDown|ButtonStateHitTest RGBA
#dn_line_sz             line height
#dn_line                RGBA
#x_curve                x curve shape value
#y_curve                y curve shape value
#text                   button text
#font_id                a font created with swf_font
#font_height            font height in pixels
#font_vertical_offset   font y offset
#font_color             font RGBA
#actions                is a string with actionscript

	sd bmem
	setcall bmem button_mem()
	#
	sd ?shape_up
	sd ?shape_over
	sd ?shape_down
	sd ?fill
	sd ?line_h
#	sd ?line
	sd ?xcurve
	sd ?ycurve

	set fill ButtonData#
	add ButtonData (DWORD);set line_h ButtonData#
	add ButtonData (8*DWORD);set xcurve ButtonData#
	add ButtonData (DWORD);set ycurve ButtonData#
	sub ButtonData (8*DWORD)
	setcall shape_up swf_shape_simple(width,height,fill,line_h,ButtonData#,xcurve,ycurve)
	add ButtonData (DWORD);set fill ButtonData#
	add ButtonData (DWORD);set line_h ButtonData#
	add ButtonData (DWORD)
	setcall shape_over swf_shape_simple(width,height,fill,line_h,ButtonData#,xcurve,ycurve)
	add ButtonData (DWORD);set fill ButtonData#
	add ButtonData (DWORD);set line_h ButtonData#
	add ButtonData (DWORD)
	setcall shape_down swf_shape_simple(width,height,fill,line_h,ButtonData#,xcurve,ycurve)

	set bmem# shape_up
	add bmem (DWORD)
	set bmem# shape_over
	add bmem (DWORD)
	set bmem# shape_down
	add bmem (DWORD)

	set bmem# width;add bmem (DWORD)
	set bmem# height;add bmem (DWORD)

	ss text
	add ButtonData (3*DWORD);set text ButtonData#v
	if text!=0
		set bmem# (FALSE)

		sd ?font_id
		add ButtonData :;add bmem (DWORD)
		set font_id ButtonData#
		set bmem# font_id

		sd ?font_height
		add ButtonData (DWORD);add bmem (DWORD)
		set font_height ButtonData#
		if font_height>^height;call error("font_height>height error at button");endif
		set bmem# font_height

		sd ?text_y
		set text_y height
		sub text_y font_height
		div text_y 2

		add ButtonData (DWORD);add bmem (DWORD)
		add text_y ButtonData#                  #font_vertical_offset
		set bmem# text_y

		sd ?font_color
		add ButtonData (DWORD);add bmem (DWORD)
		set font_color ButtonData#
		set bmem# font_color

		sd ?text_id
		setcall text_id swf_text_initial_font_centered(width,height,text,font_id,font_height,font_color)

		add ButtonData (DWORD) #actions
		callret swf_button_base(shape_up,shape_over,shape_down,ButtonData#v,(FALSE),text_id,text_y)
	end
	set bmem# (TRUE)
	add ButtonData (:+(4*DWORD)) #actions
	callret swf_button_base(shape_up,shape_over,shape_down,ButtonData#v,(TRUE))
endfunction
#id
functionX swf_button_last(ss actions,ss newtext)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#ss newtext  is the new text for a new button with the attributes from the previous swf_button call
#ss actions  button actions
	data shape_up#1
	data shape_over#1
	data shape_down#1
	data width#1
	data height#1
#	data noText#1
	data font_id#1
	data font_height#1
#	data text_y#1
#	data font_color#1
	sd p_data
	setcall p_data button_mem() #from here can also use structures like at oad
	set shape_up p_data#
	add p_data (DWORD);set shape_over p_data#
	add p_data (DWORD);set shape_down p_data#
	add p_data (3*DWORD) #set noText p_data#

	if p_data#=(FALSE)
		sd ?newtext_id
		sub p_data (DWORD);set height p_data#
		sub p_data (DWORD);set width p_data#
		add p_data (3*DWORD);set font_id p_data#
		add p_data (DWORD);set font_height p_data#
		add p_data (2*DWORD)
		setcall newtext_id swf_text_initial_font_centered(width,height,newtext,font_id,font_height,p_data#)
		sub p_data (DWORD) #text_y
		callret swf_button_base(shape_up,shape_over,shape_down,actions,(FALSE),newtext_id,p_data#)
	end
	callret swf_button_base(shape_up,shape_over,shape_down,actions,(TRUE))
endfunction

#font

#id
import "swf_font_local" swf_font_local
functionX swf_font(ss fontname,ss ?font_flags)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	callret swf_font_local(fontname,font_flags)
endfunction
#id
functionX swf_font_basic(ss fontname)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#ss fontname    = a string with the browser font, for example "_sans"
	callret swf_font_local(fontname,0)
endfunction

#text

#id
import "swf_text_local" swf_text_local
functionX swf_text(sd ?bound_width,sd ?bound_height,ss variablename,sw ?flags,sv structure)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	callret swf_text_local(bound_width,bound_height,variablename,flags,structure)
endfunction

#id
import "swf_shape_local" swf_shape_local
functionX swf_shape(sd ?width,sd ?height,sd args)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	callret swf_shape_local(width,height,args)
endfunction

#id
functionX swf_shape_basic(sd ?width,sd ?height,sd ?fillcolor,sd ?linecolor)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#sd width
#sd height
#sd fillcolor       RGBA color to fill the shape
#sd linecolor       RGBA line color around the shape
	sd ?xcurve_value;set xcurve_value width;div xcurve_value 6
	sd ?ycurve_value;set ycurve_value height;div ycurve_value 6
	sd ?lineheight;set lineheight width;if lineheight>^height;set lineheight height;endif;divu lineheight 20
	#xc width/6;yc..hg..;lh (min(w,h))/20
	callret swf_shape_simple(width,height,fillcolor,lineheight,linecolor,xcurve_value,ycurve_value)
endfunction

#id
import "swf_shape_bitmap_local_repeating" swf_shape_bitmap_local_repeating
functionX swf_shape_bitmap(sd ?bitmapId,sd ?width,sd ?height)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	callret swf_shape_bitmap_local_repeating(bitmapId,width,height)
endfunction
import "swf_shape_bitmap_local_clipped" swf_shape_bitmap_local_clipped
functionX swf_shape_bitmap_clipped(sd ?bitmapId,sd ?width,sd ?height)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	callret swf_shape_bitmap_local_clipped(bitmapId,width,height)
endfunction
#id
functionX swf_shape_border(sd ?width,sd ?height,sd ?linesize,sd ?linecolor)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#sd width      border width
#sd height     border height
#sd linesize  line size
#sd linecolor  0xRGBA color
	if linesize=0;call error("is useless to call shape_border with linesize=0");endif
	data data={no_fill,re,re,0,StateLineStyle,1,1,re,0,1,1,0,re,1,1,re,0,1,1,0,re,-1};sd p_data^data
#	data border=no_fill
#	data l_w#1
#	set l_w linesize
	add p_data (DWORD);set p_data# linesize
#	data color#1;#linesize!=0
#	set color linecolor
	add p_data (DWORD);set p_data# linecolor
	#
#	data *={0,StateLineStyle}
#	data *={1,1}
#	data est#1;data *=0
#	set est width
	add p_data (5*DWORD);set p_data# width
#	data *={1,1}
#	data *=0;data sud#1
#	set sud height
	add p_data (5*DWORD);set p_data# height
#	data *={1,1}
#	data west#1;data *=0
#	set west neg_w
	sd ?neg_w=-1
	mult neg_w width
	add p_data (3*DWORD);set p_data# neg_w
#	data *={1,1}
#	data *=0;data nord#1
#	set nord neg_h
	sd ?neg_h=-1
	mult neg_h height
	add p_data (5*DWORD);set p_data# neg_h
#	data *=-1
	callret swf_shape_local(width,height,#data)
endfunction

######################dbl

#id
functionX swf_image(ss imagepath)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#ss imagepath = path name for the dbl image
	data width#1;data *height#1
	callret swf_image_ex_local(imagepath,#width,(FALSE))
endfunction
#id
import "swf_image_ex_local" swf_image_ex_local
functionX swf_image_ex(ss imagepath,sd p_wh)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#ss imagepath, sd p_wh
	callret swf_image_ex_local(imagepath,p_wh,(FALSE))
endfunction

#id
functionX swf_dbl(ss imagepath)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#ss imagepath = path name for the dbl image
	callret swf_dbl_ex_local(imagepath,(NULL),(FALSE))
endfunction
#id
import "swf_dbl_ex_local" swf_dbl_ex_local
functionX swf_dbl_ex(ss imagepath,sd p_wh)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	callret swf_dbl_ex_local(imagepath,p_wh,(FALSE))
endfunction

import "dbl_dim" dbl_dim
#width
functionX swf_dbl_width(ss imagepath)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#ss imagepath = path name for the dbl image
	callret dbl_dim(imagepath,0)
endfunction
#height
functionX swf_dbl_height(ss imagepath)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#ss imagepath = path name for the dbl image
	callret dbl_dim(imagepath,(WORD))
endfunction

#jpeg/png/gif

import "swf_jpeg_local" swf_jpeg_local
#id
functionX swf_imagej(ss imagepath,sd ?width,sd ?height)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	sd id;setcall id swf_jpeg_local(imagepath,(DefineBitsJPEG2))
	callret swf_shape_bitmap_local_repeating(id,width,height)
endfunction
functionX swf_imagej_alpha(ss imagepath,sd ?width,sd ?height,ss alphapath)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#ss imagepath, width, height, alpha
	sd id;setcall id swf_jpeg_local(imagepath,(DefineBitsJPEG3),alphapath)
	callret swf_shape_bitmap_local_repeating(id,width,height)
endfunction
functionX swf_imagej_clipped(ss imagepath,sd ?width,sd ?height)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	sd id;setcall id swf_jpeg_local(imagepath,(DefineBitsJPEG2))
	callret swf_shape_bitmap_local_clipped(id,width,height)
endfunction
functionX swf_imagej_alpha_clipped(ss imagepath,sd ?width,sd ?height,ss alphapath)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	sd id;setcall id swf_jpeg_local(imagepath,(DefineBitsJPEG3),alphapath)
	callret swf_shape_bitmap_local_clipped(id,width,height)
endfunction

#libming is skipping at least FFE[0-F] , src/blocks/jpeg.c methodWriteJpegFile
#https://www.w3.org/Graphics/JPEG/jfif3.pdf
#https://stackoverflow.com/questions/7676701/java-jpeg-converter-for-odd-image-types
#but "Every jpeg without a JFIF header is essentially broken as there's no way of knowing what color coding is used."
#and from the time when we wrote jpegs, there are 6 values there, more at https://raw.githubusercontent.com/colin-i/ostream/refs/heads/master/src/media/jpeg_enc.oc write_jpeg_headers_appinfo
#
#https://www.w3.org/Graphics/GIF/spec-gif89a.txt
#Transparent Color Flag
#anyway, more simple is: identify -format %A a.gif
functionX swf_jpeg(ss imagepath)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#ss imagepath = path name for the dbl image
	callret swf_jpeg_local(imagepath,(DefineBitsJPEG2))
endfunction
functionX swf_jpeg_alpha(ss imagepath,ss alphapath)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#ss imagepath = path name for the dbl image
	callret swf_jpeg_local(imagepath,(DefineBitsJPEG3),alphapath)
endfunction

import "filepath_get_word" filepath_get_word
const gifsignature=6 #GIF89a
#width
functionX swf_gif_width(ss imagepath)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#ss imagepath = path name for the gif image
	#sw dim
	callret filepath_get_word(imagepath,(gifsignature),globalw.err)
endfunction
#height
functionX swf_gif_height(ss imagepath)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#ss imagepath = path name for the gif image
	#sw dim
	callret filepath_get_word(imagepath,(gifsignature+WORD),globalw.err)
endfunction

#both

import "imgx" imgx

#id
functionX swf_imagex(ss imagepath)
	base globalw.jmp_data;call ebase(globalw.jmp_data) #consider that:
	callret imgx(imagepath,(NULL),(TRUE))  #imgx has another base location and util.oc is not stacking them at the moment, if this is not last must compare or stack them
end
functionX swf_imagex_ex(ss imagepath,sd p_wh)
	base globalw.jmp_data;call ebase(globalw.jmp_data) #same
	callret imgx(imagepath,p_wh,(TRUE))    #same
end
functionX swf_img(ss imagepath)
	base globalw.jmp_data;call ebase(globalw.jmp_data) #same
	callret imgx(imagepath,(NULL),(FALSE)) #same
end
functionX swf_img_ex(ss imagepath,sd p_wh)
	base globalw.jmp_data;call ebase(globalw.jmp_data) #same
	callret imgx(imagepath,p_wh,(FALSE))   #same
end

##############
import "exportsId_get" exportsId_get
functionX swf_done()
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	call swf_exports_done_local();#remaining exports?

#	sd p;set p swf_frames_pointer()
	call swf_actionblock_done((from_done)) #,p in case there are remaining actions

#the swf is done and the total length is wrote and the memory is freed
	call swf_mem((mem_exp_done))
	call freereset()
endfunction

import "swf_new_ex_local" swf_new_ex_local
functionX swf_new_ex(ss path,sd ?width,sd ?height,sd ?backgroundcolor,ss ?fps,sd ?flags)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	call swf_new_ex_local(path,width,height,backgroundcolor,fps,flags)
endfunction

import "swf_placeobject_local" swf_placeobject_local
functionX swf_placeobject(sd ?refid,sd ?depth)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	call swf_placeobject_local(refid,depth)
endfunction
#                                                       if not data here, then will conflict at c language where we talk about int, there is =0 comparison
import "swf_placeobject_coords_local" swf_placeobject_coords_local
functionX swf_placeobject_coords(sd ?refid,sd ?depth,datax x,datax y)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	call swf_placeobject_coords_local(refid,depth,x,y)
endfunction
import "swf_removeobject_local" swf_removeobject_local
functionX swf_removeobject(sd ?depth)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	call swf_removeobject_local(depth)
endfunction

import "swf_showframe_base" swf_showframe_base
import "default_error" default_error

functionX swf_showframe()
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	call default_error()
#	sd p;set p swf_frames_pointer()
	call swf_showframe_base() #p if on error will error at unregistered input id
endfunction

######################

#sprite

import "swf_tag_end" swf_tag_end
import "done_action_one" done_action_one
#id
functionX swf_sprite_done(sd ?spriteid)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#sd spriteid        pre-id created with swf_sprite_new
    call swf_mem((mem_exp_change),spriteid)

	call swf_actionblock_change(spriteid)
	call swf_actionblock_done((from_done)) # in case there are remaining actions
	call swf_actionblock_change_back()

	call swf_tag_end()
	call swf_mem_change_back()

	sd id
	setcall id identifiers_get()

    sd sprite
    setcall sprite struct_ids((ids_get),spriteid)
    sd mem
    setcall mem block_get_mem(sprite)

	#more at dtitles
	call dtitles_conclude(id,mem)

    sd size
    setcall size block_get_size(sprite)
    #
    call swf_tag_recordheader_entry((DefineSprite),size)
    call stack_to_word_arg(id,mem)

    call swf_mem_add(mem,size)

	#if is, add DoInitAction in timeline
	call is_ainit((xlog_ainit_true))
	call done_action_one(spriteid,id)
	call free_sprite_id_actions(spriteid)

	call is_ainit((xlog_ainit_false))
	call free_sprite_id(spriteid,id)

    return id
endfunction
import "new_sprite_id" new_sprite_id
import "pool_read" pool_read
import "struct_ids_action_set" struct_ids_action_set
#pre-id
functionX swf_sprite_new()
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#a pre-id to be used
	sd ?id
	setcall id new_sprite_id()
	call pool_read(id,-1)
	call struct_ids_action_set(id,(xlog_ainit_false))
	call pool_read(id,0)
	call swf_mem((mem_exp_change),id)
	sw ?reserve;#set later
	call swf_mem_add(#reserve,2)
	sw ?frames=0
	call swf_mem_add(#frames,2)
	call swf_mem_change_back()
    return id
endfunction
functionX swf_sprite_placeobject(sd ?spriteid,sd ?object,sd ?depth)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#sd spriteid          pre-id
#sd object,sd depth   same as swf_placeobject
    call swf_mem((mem_exp_change),spriteid)
    call swf_placeobject_local(object,depth)
	call swf_mem_change_back()
endfunction
#                                                                         same
functionX swf_sprite_placeobject_coords(sd ?spriteid,sd ?object,sd ?depth,datax x,data y)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#sd spriteid                   pre-id
#sd object,sd depth,sd x,sd y  same as swf_placeobject_coords
    call swf_mem((mem_exp_change),spriteid)
    call swf_placeobject_coords_local(object,depth,x,y)
	call swf_mem_change_back()
endfunction
functionX swf_sprite_removeobject(sd ?spriteid,sd ?depth)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#sd spriteid   pre-id
#sd depth      same as swf_removeobject
    call swf_mem((mem_exp_change),spriteid)
    call swf_removeobject_local(depth)
	call swf_mem_change_back()
endfunction
functionX swf_sprite_showframe(sd ?spriteid)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#sd spriteid   pre-id
    call swf_mem((mem_exp_change),spriteid)
	call swf_actionblock_change(spriteid)
#	sd p;setcall p swf_sprite_frames_pointer(spriteid)
	call swf_showframe_base() #p
	call swf_actionblock_change_back()
	call swf_mem_change_back()
endfunction

######################

#exports

import "debug_export" debug_export
functionX swf_exports_add(sd ?id,ss name)
	base globalw.jmp_data;call ebase(globalw.jmp_data)
#sd id
#ss name       name to be used at the actionscript
	sd ?exports
	setcall exports exportsId_get()
	#
	call swf_mem((mem_exp_change),exports)
	#
	sd block
	setcall block struct_ids((ids_get),exports)
	sd ?size
	setcall size block_get_size(block)
	sd ?counter
	if size=0
		set counter 1
		call swf_mem_add(#counter,(WORD))
	else
		sd mem
		setcall mem block_get_mem(block)
		setcall counter word_arg_to_stack(mem)
		inc counter
		call stack_to_word_arg(counter,mem)
	endelse
	#
	call swf_mem_add(#id,(WORD))
	sv ?len
	setcall len strlen(name) #here can be a problem on a great string but ExportAssets has only a counter and some id/string pairs, the error is visible
	#	can work more here if wanting all good
	call debug_export(id,name,len)
	inc len
	call swf_mem_add(name,len)
	#
	call swf_mem_change_back()
endfunction
import "swf_exports_done_local" swf_exports_done_local
functionX swf_exports_done()
	base globalw.jmp_data;call ebase(globalw.jmp_data)
	call swf_exports_done_local()
endfunction

entryraw globalw()
