I am embarking on the development of an on-line design tool. This tool will be integrated into an e-commerce web site, and will allow the user/customer to specify the design for a custom printed product. For rev 1, we are going to allow the user to create rectangles, lines, circles, and text, as well as place images.

The user interface will be similar to what is found in Flash Professional or Adobe Illustrator: There will be a "Tools" area where the user can select a component (line, rectangle, etc), and then drag on the artboard to create the element. The user will be able to resize, rotate, change colors, change fonts, etc. All the standard stuff.

We expect to have a finite number of zoom levels...maybe five...available to the user, as well as full undo/redo capability.

We also have the requirement that the user be able to save their design (on the server) so that it can be re-loaded into the on-line designer at a later time. This will allow the user to (a) start a design, interrupt their session, and then complete it later or (b) use a previous design or a stock design (that we will supply) as a starting point for a new project.

The final output is required to be in PDF format, on the server, so it can be sent to our printer for production.

I have started working on this in Flash Builder 4.6.

While I have an extensive programming background (Unix/C/Tuxedo/SQL) I am totally new to AS3.

I've been noodling on this, and I have this idea that I have no clue whether it is possible or reasonable:

My idea is to create a class that inherits from "Shape" (or "Sprite"...not sure), and then have a state variable that determines what happens with a "draw" event: Normally, the "draw" behavior will draw to the default stage on the screen, but if the user presses "save", then all the "drawing" will be redirected to a series of PHP server calls that will send each individual object's meta data to the server.

So if you have a little blurb of code like this:

Actionscript Code:
var someObject:SuperShape = new SuperShape();

someObject.graphics.drawRect(0, 0, 20, 20);

under ordinary circumstances, the beginFill/drawRect/endFill stuff will just pass through to the default behavior for Shape, but if the application is in "save" mode, then those functions will re-direct to the required server calls.

Does that seem like a reasonable way to do things?

The alternative that I see is to create specific classes for each specific drawing element (ie, "DesignerLine", "DesignerText", "DesignerRectangle") and build the intelligence to either "draw or save" directly into those classes. Something like this:
Actionscript Code:
if("master-drawing-mode" == SAVE_TO_SERVER){
// make some PHP calls to send the data to the server
drawRect(0, 0, 20, 20);

The PDF output is going to be tough.

The first option I see is to create a third state for the master classes I am creating...one that will translate a "draw" event into a series of PHP calls (perhaps invoking FPDF services). The problem there is that all of the elements will need to be sent over the network twice (once to save to the database, once to save to the PDF). Since the users will have the option of placing images onto their designs, we could be looking at some pretty heavy graphics and long save times.

The second option I see is to use AlivePDF to create the PDF on the client side, and then upload it. That is probably the easiest from a programming perspective, but it has the same downside of requiring additional network traffic.

The third option would be to write some server-side code to extract the design from the database and create the PDF there (again, using FPDF). That solves the network traffic problem, but gives us more development work. On the plus side, it makes image handling easier, and that is going to be a factor. One of the behaviors required by the online designer is to specify image cropping and opacity. We can pass along the meta-data for that into the database, and then use ImageMagick on the server to process the images.

Anyway, that's where I am at. I am hoping to avoid coding my way down a dead-end, so I want to get started in the right direction. Any thoughts, comments, advice would be most welcome and appreciated.