/*--------------------------------------*/
/* $VER: txtRotator V3.05 (12 Nov 1996) */
/* ©1996 Michael Merkel                 */
/*--------------------------------------*/

/*
   how to use this:
   ----------------

   1. draw a circle/ellipse/arc/pie with PageStream3
      (please use PageStream3.1 BETA 3 or higher with this script
       due to problems with rotated text objects in earlier versions)
   2. select this object
   3. start this script
   4. press OK to see what happens

   notes:
   ------

   * this script does NOT work with rotated objects!
     (do it with the unrotated object first then group it and rotate all)
   * it only works with "normal" circles/ellipses/arcs/pies
   * text around ellipses sometimes look wierd - play with it

   comments to this program to:
   ----------------------------
      mmerkel@rummelplatz.uni-mannheim.de

   this is my first public arexx-script... don't blame me for that :-)

   IF YOU LIKE THIS SCRIPT PLEASE SEND ME A HARDCOPY OF THE
   PAGESTREAM SCREEN WITH YOUR WORK ON IT!

   happy rotating...

   Michael Merkel
*/


OPTIONS RESULTS

/* Make sure rexx support is opened */
IF ~SHOW('L','rexxsupport.library') THEN
   CALL ADDLIB('rexxsupport.library',0,-30)
IF ~SHOW('L','softlogik:libs/slarexxsupport.library') THEN
   CALL ADDLIB('softlogik:libs/slarexxsupport.library',0,-30)
IF ~SHOW('L','rexxmathlib.library') THEN
   CALL ADDLIB('rexxmathlib.library',0,-30)
ADDRESS 'PAGESTREAM'

trversion = 'V3.05'

'GETOBJECT TYPE 'typ
 ret = RESULT
if (typ ~= 7) | (ret = 10) then call DOERRORREQUESTER

defmeasure = GetDefaultMeasurementSystem()

'GETELLIPSE POSITION koordinaten ANGLES winkel'
id = result

typ = winkel.type

startw = 0
endw = 360
if winkel.type ~= 'ELLIPSE' then do
    endw = (450 - p2d(winkel.begin)) // 360
    startw = (450 - p2d(winkel.end)) // 360
    if endw < startw then endw = endw + 360
end

call ReadTXTRotatorPrefs

measure = 'pt'
posifaktor = 1
rifaktor = 1
degree = '°'
tf.0 = 'FALSE'
tf.1 = 'TRUE'

mx = koordinaten.centerx
my = koordinaten.centery
rx = koordinaten.radiusx
ry = koordinaten.radiusy

call DOREQUESTER
if ergebnis = cancelhandler THEN do
    ''defmeasure''
    EXIT
end

if tposi=1 then posifaktor = -1
if tposi=2 then posifaktor = 0

endw = endw + 360*(xfaktor-1)

if richtung = 1 then do
    rifaktor = -1
    dummy = startw
    startw = endw
    endw = dummy
end

call WriteTXTRotatorPrefs

size = p2d(textsize,measure)
r    = radius
mx   = mx
my   = my
rx   = rx
ry   = ry

/* ---------------------------------------------------------------- */

'REFRESH OFF'

'CURRENTWINDOWPATH'
 winname = RESULT

if (hidewin = 1) then 'HIDEWINDOW'

'OPENBUSYREQUESTER MESSAGE "text is placed around 'typ'..." THERMOMETER ENABLED ABORT ENABLED TOTAL 'l' CURRENT 0'
 BusyReq=result

highwinkel = -3.1415 * 0.5 + endw*3.1415/180
lowwinkel  = -3.1415 * 0.5 + startw*3.1415/180

altrx = rx
altry = ry

deltaradiusx = rx - (rx*icf)
deltaradiusy = ry - (ry*icf)

deltaradiusrundx = deltaradiusx / xfaktor
deltaradiusrundy = deltaradiusy / xfaktor

deltabuchstaben = l / xfaktor

deltaminusx = deltaradiusrundx / deltabuchstaben
deltaminusy = deltaradiusrundy / deltabuchstaben

do num = 0 to l-1
    character = SUBSTR(text,num+1,1)
    CALL setbusy(num)

    'DRAWTEXTOBJ 'mx my' INFRONT'
     textid = RESULT
    'SELECTTEXT AT 'mx my' FRONTMOST'
    'BEGINCOMMANDCAPTURE'
     'SETTYPESIZE 'size
     'SETTYPEWIDTH 100%'
     'SETTRACKING NONE'
     'SETLEADING RELATIVE 100%'
     'SETPARAGRAPHSTYLE 'charstyle
    'ENDCOMMANDCAPTURE'
    'INSERT "'character'"'
    'ROTATE 0'degree
    'GETTEXTOBJ POSITION txtpos2 OBJECTID 'textid

    if icf ~= 1 then txtpos2 = SCALEOBJECT(txtpos2,textid,(rx/altrx))

    txtheight = txtpos2.bottom - txtpos2.top
    txtwidth  = txtpos2.right - txtpos2.left

    if (l>1) then sinus = (highwinkel-lowwinkel) / (l-1) * num + lowwinkel
    else          sinus = (highwinkel-lowwinkel) * num + lowwinkel

    dreh = sinus * 180 / 3.1415

    sinusresult   = sin(sinus)
    cosinusresult = cos(sinus)

    nrx = rx + (txtheight/2)*posifaktor
    nry = ry + (txtheight/2)*posifaktor

    xx2 = mx + cosinusresult * nrx
    yy2 = my + sinusresult   * nry

    movx = (xx2-mx-(txtwidth/2))
    movy = (yy2-my-(txtheight/2))

    'MOVE OFFSET 'movx movy' OBJECTID 'textid

    /* Berechnen des Buchstaben-Drehwinkels */

    x0 = cosinusresult * rx
    y0 = sinusresult   * ry

    if y0 = 0 then
	dreh = -3.1415 / 2
    else do
	dreh = (x0*ry*ry)/(y0*rx*rx)
	dreh = atan(dreh)
    end
    dreh = 180 + dreh * 180 / 3.1415

    if (y0 * rifaktor) > 0 then
	'ROTATE 'dreh degree
    else
	'ROTATE '180+dreh degree

    if SUBSTR(text,num+1,1)==' ' then 'DELETEOBJECT objectid 'textid

    rx = rx - deltaminusx
    ry = ry - deltaminusy
end

call CLEANUP(1)

DOREQUESTER:
    l = 0
    do while (l<1)
	'ALLOCAREXXREQUESTER "text around 'typ trversion'©1996 Michael Merkel" 320 205'
	 reqhandle = RESULT
	'ADDAREXXGADGET 'reqhandle' EXIT 10  185 70 LABEL "_Ok"'
	 okhandler = RESULT
	'ADDAREXXGADGET 'reqhandle' EXIT 240 185 70 LABEL "_Cancel"'
	 cancelhandler = RESULT

	'ADDAREXXGADGET 'reqhandle' STRING 150 10 50 STRING "'startw'" LABEL "angles (°) start:"'
	 start_gadget = RESULT
	'ADDAREXXGADGET 'reqhandle' STRING 250 10 50 STRING "'endw'" LABEL "end:"'
	 end_gadget = RESULT
	'ADDAREXXGADGET 'reqhandle' STRING 86 30 50 STRING "'textsize'" LABEL "fontsize:"'
	 s_gadget = RESULT
	'ADDAREXXGADGET 'reqhandle' STRING 200 30 115 STRING "'charstyle'" LABEL "style:"'
	 style_gadget = RESULT
	'ADDAREXXGADGET 'reqhandle' STRING 10 60 305 STRING "'text'" LABEL "text to be placed:" LABELPOS "ABOVELEFT"'
	 t_gadget = RESULT

	'ALLOCAREXXLIST'
	 rexxlist = RESULT
	'ADDAREXXLIST 'rexxlist' "above line"'
	'ADDAREXXLIST 'rexxlist' "below line"'
	'ADDAREXXLIST 'rexxlist' "on line"'
	'ADDAREXXGADGET 'reqhandle' CYCLE 94 90 120 LABEL "place text"'
	 c_gadget = RESULT
	'SETAREXXGADGET 'reqhandle c_gadget' LIST 'rexxlist' CURRENT 'tposi

	'ALLOCAREXXLIST'
	 rexxlist2 = RESULT
	'ADDAREXXLIST 'rexxlist2' "clockwise"'
	'ADDAREXXLIST 'rexxlist2' "counterclockwise"'
	'ADDAREXXGADGET 'reqhandle' CYCLE 46 110 168 LABEL "text"'
	 ri_gadget = RESULT
	'SETAREXXGADGET 'reqhandle ri_gadget' LIST 'rexxlist2' CURRENT 'richtung

	'ADDAREXXGADGET 'reqhandle' STRING 174 130 40 STRING "'icf'" LABEL "inner circle factor:"'
	 icf_gadget = RESULT

	'ADDAREXXGADGET 'reqhandle' STRING 126 145 40 STRING "'xfaktor'" LABEL "surrounding #:"'
	 xfaktor_gadget = RESULT

	'ADDAREXXGADGET 'reqhandle' CHECKBOX 10 165 10 CHECKED "'tf.hidewin'" LABEL "hide window while drawing (faster!)"'
	 hidewin_gadget = RESULT

	'DOAREXXREQUESTER 'reqhandle
	 ergebnis = RESULT

	'GETAREXXGADGET 'reqhandle start_gadget' STRING'
	 startw = RESULT
	'GETAREXXGADGET 'reqhandle end_gadget' STRING'
	 endw = RESULT
	'GETAREXXGADGET 'reqhandle s_gadget' STRING'
	 textsize = RESULT
	'GETAREXXGADGET 'reqhandle style_gadget' STRING'
	 charstyle = RESULT
	'GETAREXXGADGET 'reqhandle t_gadget' STRING'
	 text = RESULT
	 l = length(text)
	'GETAREXXGADGET 'reqhandle c_gadget' CURRENT'
	 tposi = RESULT
	'GETAREXXGADGET 'reqhandle ri_gadget' CURRENT'
	 richtung = RESULT
	'GETAREXXGADGET 'reqhandle icf_gadget' STRING'
	 icf = RESULT
	'GETAREXXGADGET 'reqhandle xfaktor_gadget' STRING'
	 xfaktor = RESULT
	'GETAREXXGADGET 'reqhandle hidewin_gadget' CHECKED'
	 hidewin = RESULT
	'FREEAREXXREQUESTER 'reqhandle
	'FREAREXXLIST 'rexxlist
	'FREAREXXLIST 'rexxlist2
    end
RETURN

DOERRORREQUESTER:
    say 'Error: No circle/ellipse/arc/pie selected!'

    'ALLOCAREXXREQUESTER "Error!" 400 70'
     reqhandle = RESULT
    'ADDAREXXGADGET 'reqhandle' EXIT 165 50 70 LABEL "_Ok"'
     dummy = RESULT

    'ADDAREXXGADGET 'reqhandle' TEXT 10 10 390 STRING "You did not chose an arc/ellipse/circle/pie!"'
    'ADDAREXXGADGET 'reqhandle' TEXT 10 30 390 STRING "Select one and start me again!"'

    'DOAREXXREQUESTER 'reqhandle
     dummy = RESULT

    'FREEAREXXREQUESTER 'reqhandle
    exit
RETURN

SCALEOBJECT:
    ARG txtpos2,objectidnew,factor

    txt_x = txtpos2.left
    txt_y = txtpos2.top
    txt_xx = txtpos2.right
    txt_yy  = txtpos2.bottom
    txtheight = txt_yy - txt_y
    txtwidth  = txt_xx - txt_x

    newtxt_x = txt_x + txtwidth * factor
    newtxt_y = txt_y + txtheight * factor
    'EDITTEXTOBJ POSITION 'txt_x txt_y newtxt_x newtxt_y' OBJECTID 'objectidnew
    'GETTEXTOBJ POSITION txtpos2 OBJECTID 'textid
RETURN txtpos2

SETBUSY:
    parse arg value

    infonewtext = SUBSTR(text,1,value)||'['||substr(text,value+1,1)||']'||substr(text||' ',value+2)
    infochar    = SUBSTR('...............'||infonewtext||'..............',value+1,30)

    'SETBUSYREQUESTER 'BusyReq' CURRENT 'value' MESSAGE "'infochar'"'
    'GETBUSYREQUESTER 'BusyReq
    if result=1 then call CLEANUP(1)
RETURN

CLEANUP:
    'CLOSEBUSYREQUESTER 'BusyReq
    ''defmeasure''
    if (hidewin = 1) then 'REVEALWINDOW WINDOW "'winname'"'
    'REFRESH ON'
    'REFRESHWINDOW'
EXIT

ReadTXTRotatorPrefs:
    ok = Open('Prefs','PageStream3:Scripts/txtRotator.prefs','R')
    if ok = 1 then do
	say 'reading old prefs...'
	textsize = ReadLN('Prefs')
	charstyle = ReadLN('Prefs')
	text = ReadLN('Prefs')
	tposi = ReadLN('Prefs')
	richtung = ReadLN('Prefs')
	icf = ReadLN('Prefs')
	xfaktor = ReadLN('Prefs')
	hidewin = ReadLN('Prefs')
	Close('Prefs')
	end
    else do
	say 'unable to read prefs -> default values'
	textsize = '20pt'
	charstyle = 'RoundText'
	text = 'abcdefghijklmnopqrstuvwxyz0123456789 '
	tposi = 0
	richtung = 0
	icf = 1
	xfaktor = 1
	hidewin = 0
    end
RETURN

WriteTXTRotatorPrefs:
    ok = Open('Prefs','PageStream3:Scripts/txtRotator.prefs','W')
    if ok = 1 then do
	say 'writing prefs...'
	WriteLN('Prefs',textsize)
	WriteLN('Prefs',charstyle)
	WriteLN('Prefs',text)
	WriteLN('Prefs',tposi)
	WriteLN('Prefs',richtung)
	WriteLN('Prefs',icf)
	WriteLN('Prefs',xfaktor)
	WriteLN('Prefs',hidewin)
	Close('Prefs')
	end
    else do
	say 'error writing prefs file "txtRotator.prefs"'
    end
RETURN

GetDefaultMeasurementSystem:
    PROCEDURE

    'GETMEASUREMENTS COORDINATE stemc RELATIVE rel TEXT tex FROM fro'
    st = 'SETMEASUREMENTS COORDINATE 'stemc.horizontal stemc.vertical' RELATIVE 'rel' TEXT 'tex' FROM 'fro
    'SETMEASUREMENTS COORDINATE POINTS SAMEAS RELATIVE SAMEAS TEXT POINTS FROM PAGE'
RETURN st
