/*@BBordureObjetsComplexes @P@I Ecrit et © par Don Cox en juillet 92
@IN'est pas du Domaine Publique. Tous Droits Réservés.
Traduit par Fabien Larini le 17/07/93.

Ce Génie encadre les boîtes avec un dessin dans chaque coin et un motif
composé de plusieurs dessins. Il a besoin d'une boîte contenant le dessin
(clip ou bitmap) pour les coins, de une ou plusieur boîtes similaires pour
le motif des côtés. La bordure réalisée, est groupée avec la boîte à 
encadrer, pour déplacer l'ensemble, appuyer sur Shift.
*/


/*BordersRepeats*/
/* This Genie puts a decorative border around a box. You will need a box containing a clip or bitmap for the corners, and one or more similar boxes for the sides. The resulting border consists of a group of individual boxes, which can be moved together if you hold down the shift key.
Written by Don Cox  July '92. Not Public Domain. All rights reserved.  */

trace n

address command
signal on error
signal on syntax
signal on halt
signal on break_c
signal on break_d
signal on break_e

rad = 3.1415926 / 180
call ppm_AutoUpdate(0)
call SafeEndEdit.rexx()
cr="0a"x

if ~show('l', "gdarexxsupport.library") then
    if ~addlib("gdarexxsupport.library",0,-30) then
            call exit_msg("Installez la gdarexxsupport.library dans le répertoire libs: avant de lancer ce Génie")

CurrentUnits = ppm_GetUnits()

select
    when CurrentUnits = 1 then units="inches"
    when CurrentUnits = 2 then units="millimetres"
    otherwise units ="points"
    end

mainbox = ppm_ClickOnBox("Clickez sur la Boîte à Encadrer")
if mainbox=0 then exit_msg("Pas de Boîte Selectionnée")
mainpos = ppm_GetBoxPosition(mainbox)
mainXpos = word(mainpos, 1)
mainYpos = word(mainpos, 2)
mainsize = ppm_GetBoxSize(mainbox)
mainangle = ppm_GetBoxAngle(mainbox)

breadthRaw =  ppm_GetUserText(6, "Largeur du cadre en "units)
if breadthRaw="" then exit_msg("Abandon Utilisateur")

if CurrentUnits = 2 then breadth = breadthRaw/10   /* mm to cm */
if CurrentUnits = 3 then breadth = breadthRaw/12   /* points to picas */
mainheight = (word(mainsize, 2))-(breadth*2)
mainwidth = (word(mainsize, 1))-(breadth*2)
if mainheight<0 | mainwidth<0 then exit_msg("Largeur Impossible : "breadthRaw)

cornerbox = ppm_ClickOnBox("Clickez dans la Boîte contenant le Dessin des Coins")
if cornerbox ~=0 then do
    csize = ppm_GetBoxSize(cornerbox)
    cXsize = word(csize, 1)
    cYsize = word(csize, 2)
    cscale = ppm_GetBoxScale(cornerbox)
    cscaleX = word(cscale, 1)
    cscaleY = word(cscale, 2)
    cangle = ppm_GetBoxAngle(cornerbox)
    end

counter=0

do forever
    box=ppm_ClickOnBox("Clickez dans les Boîtes contenant le(s) Dessin(s) pour le Motif des Cotés")
    if box=0 then break
    counter=counter+1
    boxes.counter=box
    call ppm_SetBoxAngle(box,0)
    if counter = 5 then break
end
                       
if counter = 0 & cornerbox = 0 then exit_msg("Pas de Dessins pour les Coins et les Bords")

sideboxes = counter /* This is the number of different units in the design */

do while counter<6
    counter = counter+1
    boxes.counter = boxes.1    /* pad up to 5 */
    end



if Sideboxes>1 then do
    pattern = ppm_GetUserText(Sideboxes*3, Sideboxes" boîtes selectionnées. Tapez un motif de répétition en utilisant abBAc etc.")
    if pattern = "" then pattern = "a"
    end
else if Sideboxes = 1 then pattern = "a"

/* Place Corner Units */
call ppm_NewGroup()
call ppm_ShowStatus("Placement des Coins")
if cornerbox ~=0 then do
    cbox = ppm_CloneBox(cornerbox, 0, 0)
    call ppm_AddToGroup(cbox)
    call ppm_SetBoxAngle(cbox,0)
    call ppm_SetBoxSize(cbox, breadth, breadth)
    call ppm_SetBoxScale(cbox, cscaleX*breadth/cXsize, cscaleY*breadth/cYsize)
    call ppm_SetBoxPosition(cbox, mainXpos, mainYpos)
    cbox2 = ppm_CloneBox(cbox, 0, 0)
    call ppm_AddToGroup(cbox2)
    call ppm_SetBoxPosition(cbox2, mainXpos, mainYpos+mainheight+breadth)
    call ppm_SetBoxAngle(cbox2, (cangle+90)//360)
    cbox3 = ppm_CloneBox(cbox, 0, 0)
    call ppm_AddToGroup(cbox3)
    call ppm_SetBoxPosition(cbox3, mainXpos+mainwidth+breadth, mainYpos+mainheight+breadth)
    call ppm_SetBoxAngle(cbox3, (cangle+180)//360)
    cbox4 = ppm_CloneBox(cbox, 0, 0)
    call ppm_AddToGroup(cbox4)
    call ppm_SetBoxPosition(cbox4, mainXpos+mainwidth+breadth, mainYpos)
    call ppm_SetBoxAngle(cbox4, (cangle+270)//360)
    call ppm_SetBoxAngle(cbox, cangle//360)
    end


if Sideboxes = 0 then exit_msg("Terminé")

    patternlength = length(pattern)
    totalwidth = 0


    do i=1 to patternlength
        letter = substr(pattern, i, 1)
        select
            when letter = "a" | letter = "A" then repeats.i = ppm_CloneBox(boxes.1, 0, 0)
            when letter = "b" | letter = "B" then repeats.i = ppm_CloneBox(boxes.2, 0, 0)
            when letter = "c" | letter = "C" then repeats.i = ppm_CloneBox(boxes.3, 0, 0)
            when letter = "d" | letter = "D" then repeats.i = ppm_CloneBox(boxes.4, 0, 0)
            when letter = "e" | letter = "E" then repeats.i = ppm_CloneBox(boxes.5, 0, 0)
            otherwise repeats.i = ppm_CloneBox(boxes.1, 0, 0)
            end

            if datatype(letter, "upper") then repeats.i.flip = 1
            else repeats.i.flip = 0


/* Collect original size and graphic scale of each box */
    repeats.i.scaleX = word(ppm_GetBoxScale(repeats.i), 1)
    repeats.i.scaleY = word(ppm_GetBoxScale(repeats.i), 2)
    repeats.i.width = word(ppm_GetBoxSize(repeats.i), 1)
    repeats.i.height = word(ppm_GetBoxSize(repeats.i), 2)
    repeats.i.scale1 = breadth/repeats.i.height
    repeats.i.width2 = repeats.i.width*repeats.i.scale1
    if repeats.i.flip = 1 then repeats.i.scale1 = -repeats.i.scale1

    totalwidth = totalwidth+repeats.i.width2   /* width of the whole pattern */
end


heightcount = mainheight%totalwidth /* Use integer division to get number of repeats */
widthcount = mainwidth%totalwidth
if widthcount = 0 | heightcount = 0 then exit_msg("Motif trop Grand")

Xtotalwidth = mainwidth/widthcount  /* Exact width of whole pattern */
Ytotalwidth = mainheight/heightcount
Xscale = Xtotalwidth/totalwidth
Yscale = Ytotalwidth/totalwidth

do i = 1 to patternlength
    repeats.i.widthX = repeats.i.width2*Xscale
    repeats.i.widthY = repeats.i.width2*Yscale 
    end


/* Place top units  */

call ppm_ShowStatus("Placement du Bord Supérieur")
leftpos = mainXpos+breadth
do j=1 to widthcount
do i=1 to patternlength
    newboxes.i = ppm_CloneBox(repeats.i, 0, 0)
    call ppm_AddToGroup(newboxes.i)
    call ppm_SetBoxSize(newboxes.i, repeats.i.widthX, breadth)
    call ppm_SetBoxPosition(newboxes.i, leftpos, mainYpos)
    call ppm_SetBoxScale(newboxes.i, (repeats.i.scaleX *repeats.i.scale1* Xscale), (repeats.i.scaleY * abs(repeats.i.scale1)) )
    call ppm_SetBoxAngle(newboxes.i, 0)
    leftpos = leftpos+repeats.i.widthX
    end
end

/* Place right side units */
call ppm_ShowStatus("Placement du Bord Droit")
toppos = mainYpos+breadth
leftpos = mainXpos+word(mainsize, 1)

do j=1 to heightcount
    do i=1 to patternlength
        newboxes.i = ppm_CloneBox(repeats.i, 0, 0)
        call ppm_AddToGroup(newboxes.i)
        call ppm_SetBoxAngle(newboxes.i, 270)
        call ppm_SetBoxSize(newboxes.i, repeats.i.widthY, breadth)
        call ppm_SetBoxPosition(newboxes.i, leftpos, toppos)
        call ppm_SetBoxScale(newboxes.i, (repeats.i.scaleX *repeats.i.scale1* Yscale), (repeats.i.scaleY * abs(repeats.i.scale1)) )
        toppos = toppos+repeats.i.widthY
        end 
    end


/* Place bottom units  */

call ppm_ShowStatus("Placement du Bord Inférieur")
leftpos = mainXpos+breadth+mainwidth
toppos = mainYpos+word(mainsize, 2)

do j=1 to widthcount
do i=1 to patternlength
    newboxes.i = ppm_CloneBox(repeats.i, 0, 0)
    call ppm_AddToGroup(newboxes.i)
    call ppm_SetBoxAngle(newboxes.i, 180)
    call ppm_SetBoxSize(newboxes.i, repeats.i.widthX, breadth)
    call ppm_SetBoxPosition(newboxes.i, leftpos, toppos)
    call ppm_SetBoxScale(newboxes.i, (repeats.i.scaleX *repeats.i.scale1* Xscale), (repeats.i.scaleY * abs(repeats.i.scale1)) )
    leftpos = leftpos-repeats.i.widthX
    end
end

/* Place left side units */
call ppm_ShowStatus("Placement du Bord Gauche")
toppos = mainYpos+breadth+mainheight
leftpos = mainXpos

do j=1 to heightcount
    do i=1 to patternlength
        newboxes.i = ppm_CloneBox(repeats.i, 0, 0)
        call ppm_AddToGroup(newboxes.i)
        call ppm_SetBoxAngle(newboxes.i, 90)
        call ppm_SetBoxSize(newboxes.i, repeats.i.widthY, breadth)
        call ppm_SetBoxPosition(newboxes.i, leftpos, toppos)
        call ppm_SetBoxScale(newboxes.i, (repeats.i.scaleX *repeats.i.scale1* Yscale), (repeats.i.scaleY * abs(repeats.i.scale1)) )
        toppos = toppos-repeats.i.widthY
        end 
    end

/* Delete the "repeats" set of boxes  */
do i = 1 to patternlength
    gone = ppm_DeleteBox(repeats.i)
    end

/* Set an arbitrary margin in main box  */
margin = breadth*1.5
call ppm_SetBoxMargins(mainbox, margin, margin, margin, margin)

/* Rotate border to match main box. This routine is just the Group Rotate genie. */

if mainangle~=0 then do
    box     = ppm_GroupFirstBox()
    if box  = 0 then exit_msg("Choisissez d'abord un Groupe")


    rangle  = mainangle * rad
    cosa    = cos(rangle)
    sina    = sin(rangle)

    call ppm_ShowStatus("Rotation ...")

    grouprect   = ppm_GetGroupRect()
    grpleft     = word(grouprect, 1)
    grptop      = word(grouprect, 2)

    do while box ~= 0

        boxpos  = ppm_GetBoxPosition(box)
        boxleft = word(boxpos, 1)
        boxtop  = word(boxpos, 2)

        newangle = (mainangle + ppm_GetBoxAngle(box))//360
        call ppm_SetBoxAngle(box, newangle )

        xoffset = boxleft - grpleft
        yoffset = boxtop - grptop

        x   = grpleft + xoffset * cosa + yoffset * sina
        y   = grptop +  yoffset * cosa - xoffset * sina

        call ppm_SetBoxPosition(box, x, y)

        box = ppm_GroupNextBox(box)
    end
end 

call exit_msg()

end

error:
syntax:
    do      
    exit_msg("Arrêt du Génie dû à l'erreur: "errortext(rc))
    end

break_d:
break_e:
break_c:
halt:
call exit_msg("Arrêté par l'Utilisateur")

exit_msg:
    do
    parse arg message
    if message ~= "" then
    call ppm_Inform(1, message,)
    call ppm_ClearStatus()
    call ppm_AutoUpdate(1)
    exit
    end

