  // HPPenPlotter.js
  //
  // This file is a plug-in for the QCAD/CAM software.
  // Do NOT edit this file. Your changes will be lost when the
  // software is updated or reinstalled. 
  //
  // HPGL postprocessor for HP Penplotter (HP7580).
  // Only supporting HPGL (/1) as dump.plt-file.
  // Papersize A1-Plus for plotting area of
  // 420 x 297 mm minimal, to plot A3 1:1
  //
  // Rev  Date        By   Description
  // -    15-11-2018  HJS  Copied from HPGL.js
  // A    15-11-2018  HJS  Comments, info added, file altered.
  // B    16-11-2018  HJS  File Header changed.
  //                       HPGL (1.0) commands info added
  //                       Tool(pen) change added
  //                       Single toolpath per line
  //                       Footer changed
  // C    28-11-2018  HJS  Released for QCAD/CAM
  // ==================================================================
  //    Hewlett-Packard Graphics Language (HPGL release 1) was developed 
  // as an interactive penplotter plugin to BASIC.  HPGL/2 is a later 
  // update with more interactive commands.  As a form of data compression
  // the 'polyline' encoding was added. 
  //    PCL was introduced replacing the pen with the inkjet printhead.
  // PCL-printers usually supports HPGL.
  //    HPGL machines locates the lower left corner as the machine- and 
  // workpiece zero point (Origin; not Home). In HPGL 'Homing' is relocating the
  // pen-carriage to a 'View'-position.  On large size format machines
  // the origin is often located at the center of the machined measured size.
  // Relocating Center origin to lower left corner requires interactive operation.
  // A preplot recalculation is the commonly used method for origin replacement.
  //    Today HPGL is still used mainly in 'dump.plt' method for controlling 
  // pen plotters, vinyl cutters, engravers, and laser plotters.
  // (Plotters = HPGL , CNC Machine = G-Code)
  //    Gerber machines often uses the HPGL/2 interactive intelligent mode,
  // where as in 'dump-mode' the HPGL machine is fed only with the basic 
  // drafting PA- and AA-commands for executing.
  //    However HPGL can proces user coord systems in mm or inch, it is rare.
  // In 'dump-mode' most applications will use the plu-coord system. 

  
  // HPGL is generated by CamExporterV2
include("scripts/Cam/CamExportV2/CamExporterV2.js");

  // Define function HPPenPlotter.
function HPPenPlotter(cadDocumentInterface, camDocumentInterface) {
    // call constructor of base class 'CamExporterV2':
    CamExporterV2.call(this, cadDocumentInterface, camDocumentInterface);

    // If CAD-file is empty...
    if (isNull(cadDocumentInterface)) {
        // constructor used as prototype:
        return;
    }
    
    // Else, if CAD-file NOT empty...
    // Set CamExporterV2-vars
    //
    // File-path
    this.outputOffsetPath = true;               // File-path
    this.decimals = 4;                          // Tolerance ; CAD-drawing tolerance
    this.unit = RS.Millimeter;                  // Default CAM-measurement units
    // this.scale = 1;                          // Output scale-factor (scale * x, scale * y, scale * z)  
    this.scale = 40.0;                          // (Ab)use of Scale to HP-Steppermotor steps per unit; 
                                                // 1 mm = 40 plu (steps)
                                                // (Plotter finest resolution 1/40 = 0.025 mm (0.001 in.))
    this.separator = ";";                       // HPGL-Command separator 
    this.lineEnding = "";                       // Every written HPGL-line ends with ...  
    this.fileExtensions = [ "plt" ];            // Add as extension ' .plt ' to the current CAD-filename.
                                                // 
                                                // Set Array-vars for calculation by CamExporterV2
    //   array,           name,               ID,       always, prefix,decimals,    options     
    this.registerVariable("tool",             "T",       true,    "",   0);
    this.registerVariable("spindleSpeed",     "S",       true,    "",   "DEFAULT", "DEFAULT");
    this.registerVariable("feedRate",         "F",       true,    "",   "DEFAULT", "DEFAULT");
    this.registerVariable("xStartPosition",   "X1",      true,    "",   "DEFAULT", "DEFAULT");
    this.registerVariable("yStartPosition",   "Y1",      true,    "",   "DEFAULT", "DEFAULT");
    this.registerVariable("xPosition",        "X",       true,    "",   "DEFAULT", "DEFAULT");
    this.registerVariable("yPosition",        "Y",       true,    "",   "DEFAULT", "DEFAULT");
    this.registerVariable("iArcCenterAbs",    "IA",      true,    "",   "DEFAULT", "DEFAULT");
    this.registerVariable("jArcCenterAbs",    "JA",      true,    "",   "DEFAULT", "DEFAULT");
    this.registerVariable("arcSweep",         "SWEEP",   true,    "",   "DEFAULT", { factor: 360/Math.PI/2 });

    
    // ===PLT-FILE-HEADER====================================================
    // >>> Setup RS232 Communication, Creating init/reset commands <<<
    //                  ; Device Control Instruction(DCI)
    //                  ; Esc-code (ASCII(027)),           \u001B
    //                  ; Plotter On                       .(      or      .Y
    //                  ; Command delimiter                ;
    //                  ; Parameter/Command delimiter      :
    //                  ; Line Feed (Enter)                \n      or      LF
    //                  ; Comments; HPGL does not support comments, however, 
    //                  ; if no command-codes are used, one can abuse the 
    //                  ; command delimiter to add comments.
    //                  ;
    // \u001B.(;        ; RS232 Device On 
    //                  ; (Set Plotter On Line)
    // \u001B.I81;;17:  ; Set Handshake mode 2 (Xon-Xoff)
    //                  ; (I(nit) Xon at 81 empty bytes )
    //                  ; (;; Xon triggers DCI          )
    //                  ; (17: set Xon-Xoff handshake   )
    // \u001B.N;19:     ; Extended Handshake mode settings...
    //                  ; 19: InterCharacter delay time 19 msec
    //                  ; (Hardwire RAM buffer control  )
    // \u001B.A;        ; Interactive!  Outputs plotter Make and Model.
    //                  ;
    // IN;              ; Init. Initialize (resets) plotter to start up state
    //                  ; An Init executes the following commands;
    //                  ; LT0;PA;CT;SC;IM;IW;PT;PU;
    // LT;              ; Line Type. Resets to default (-6...6)
    //                  ; LT0 = Continuous
    //                  ; LT1 = ......................................
    //                  ; LT2 = ----    ----    ----    ----    ----
    //                  ; LT3 = -----   -----   -----   -----   -----
    //                  ; LT4 = ----- . ----- . ----- . ----- . ----- 
    //                  ; LT5 = ---- -  ---- -  ---- -  ---- -  ---- -
    //                  ; LT6 = --- - - --- - - --- - - --- - - --- - -
    // CT;		; Chord angle, set to 5 degrees.
    // IM;		; Interactive! Recognize all HPGL errors
    // IW;              ; Interactive! Input Window set to hard clip limits
    // PT;              ; Set units to metric, Pen width 0,3 mm.
    //                  ; (Use 0,3 mm pen to create line widths and hatches)
    // DF;              ; DeFault. Presets default values in plot batches.
    // ;                ; Empty command, clears input buffer
    // AP;              ; Store pen after 10 seconds no motion (prevents drying out)
    // RO;              ; ROtate. Rotate orientation on HP-plotter (If available!)  
    //                  ; RO;           Reset rotation (zero degrees default)
    //                  ; RO0;          Set rotation to zero degrees.
    //                  ; RO90;         Set rotation 90 degrees clockwise.
    // IP;              ; Initial Point; Sets up a plotting area from P1 to P2 within plu-coord system.
    //                  ;               (IP sets up an 'plotting area', a window    )
    //                  ;               (into wich the drawing will be plotted.     )
    //                  ;               (A following SC-command sets the scale-size.) 
    //                  ; Syntaxt:  IP[P1],[P2]         EFFECTS SC-command!	
    //                  ; IP;                           Reset User Coordinaat System to Plot Area Center.
    //                  ; IP0,0;                        Set P1x,P1y as lower left corner plotting area
    //                  ;                               (On a Center origin machine 0,0 IS the center)
    //                  ;                               (Use IP-xplu,-yplu to move origin to lower left.)
    //                  ; IP0,0,16800,11880;	        P1 = 0,0 (plu) P2=(210*40),(297*40);
    //                  ;                               (A3 as 1:1 Center-zero-point on A1 sized sheet)
    //                  ; IP-16800,-11880,0,0;	        Move P1 (A3-zeropoint) on HP7580 A1 size loaded
    //                  ; IP-16800,-11880,16800,11880;  Move A3-zeropoint to P1 (-16800,-11880 plu = 0,0),
    //                  ;                               move A3 max to P2 (16800,11880 plu = 420,297)
    //                  ;                               (Scaled A3 as 2:1 on A1 size sheet)
    // SC;              ; Scale. x-range-versus-y-range ratio setting. (Range-limits, NOT coords!)
    //                  ; SC; = (Re)Sets x,y-range to default ratio 1:1, 
    //                  ;       Origin starts at IP-setting (Default Centered on a HP7580).
    //                  ;       P1=LowerLeftLimit  P2=UpperRightLimit
    //                  ;       On a HP7580 Machine Coord System 0,0 plu is set as plot area Center.  
    //                  ; Syntax:  SC,Xmin,Xmax,Ymin,Ymax; (HPGL/1)    
    //                  ; Syntax:  SC,Xmin,Xmax,Ymin,Ymax [,type [,left,bottom] [,Xfactor,Yfactor] ]; HPGL/2
    //                  ;       type 0 = Anisotropic ratio ,
    //                  ;       type 1 = Isotropic ratio
    //                  ;       type 2 = Point factor; P1 user-unit location, ratio plotter to user
    //                  ;       left = 0...100 (percent), default 50%
    //                  ;       bottom = 0...100 (percent), default 50%
    //                  ;       xfactor = 1 , Calibrationfactor X
    //                  ;       yfactor = 1 , Calibrationfactor Y
    //                  ; SC0,40,0,40,2,0,0;	.PLT-units in mm, Should plot 1 mm in 40 plu, isotropic,
    //                  ;                       origin lowerleft. (HPGL/2 only?)
    //                  ; SC0,420,0,297,1;	.PLT-units in plu, plot A3 1:1 on HP7580 when A1 size 
    //                  ;                       loaded   
    // PU;PU;           ; Pen Up, Pen Up (HP7580 Pen Up-init and Homing, unload Pen in carriage).
    // SP;              ; Select Pen (tool select) (0...8). 
    //                  ; Resets to defaults (no pen in carriage please!)
    // SP1;             ; Select Pen 1 (and mount in carriage)
    // AS;		; Acceleration Set. Acceleration in g-force, (1...4)
    //                  ; AS1;   = slown down all pen accelerations to 1 g
    //                  ; AS1,2; = set acceleration to 1 g for pen 2   
    // VS;              ; Velocity Set (Use: Tool Feed Rate F to set). (0...60 cm/sec)
    //                  ; Resets all velocities to 1 cm/sec.
    //                  ; (Default Velocity is set by used carousel.                      )
    //                  ; (On Display, values are rounded to closest tenth-decimal.       )
    //                  ; (VS4 = 0 , VS5 = 1 , VS14 = 1 , VS15 = 2 , a.s.o.               )
    //                  ; (Note: Rapid speed can not be set; machine highest will be used.)
    // VS50,3;          ; Velocity Set at 50 cm/sec to pen 3
    //                  ; VS60 = Set all pen velocities to 60 cm/sec 
    //                  ;        Preferred for Roller ball pens.
    //                  ; VS50 = Preferred for Fibre tip pens
    //                  ; VS10 = Preferred for Drafting ink pens
    // FS;              ; Force Select. (Use Tool Spindle Speed S to select.) 
    //                  ; (Select force for pen, cutter (cut depth), laser brightness.      )
    //                  ; (Note: on HP plotters one SELECTs a preset-value, NOT setting it! )
    //                  ; FS; = Select pen force zero.
    // FS2,6;           ; Force Select 18 grams to pen 6.
    //                  ; FS66 = Set all pen forces to 50 grams
    //                  ; FS36 = Set alle pen forces to nearest value (=34 grams)
    //                  ; 1 = 10 grams (inkpen)		5 = 42 grams
    //                  ; 2 = 18 grams (fiber-tip)	6 = 50 grams (roller ball)
    //                  ; 3 = 26 grams			7 = 58 grams
    //                  ; 4 = 34 grams			8 = 66 grams
    // OP;              ; Interactive!  Outputs Plotter P1 and P2 in plu.
    // SO;              ; Gerber, NOT HPGL!  Set Origin. The drawing origin is set at the actual position.


    // ===PLT-FILE-HEADER==================================================================
    // // original QCAD :
    // this.header = "\u001B.(;\u001B.I81;;17:\u001B.N;19:IN;SC;PU;VS;VS36;SP1;PU;";
    //                  ;  
    //                  ; First line	; On line, Protocol, Init and Reset
    //                  ; Second line	; Preset common settings, Pen Speed en Pen Force
    //                  ;               ; (default values fiber tip pens)
    //                  ; Third line 	; Define plot area IP, and scaling SC.
    //                  ;               ; 1. Measure the required left-down movement in mm. (-420,-297mm)
    //                  ;               ; 2. Set IP negative measurements * 40
    //                  ;               ;    -420*40= -16800 , -297*40= -11880
    //                  ;               ; 3. IP-16800,-11880;  Move origin to ...
    //                  ; Fourth line	; Special user defined settings
    this.header = ";..Set up RS232-protocol;\n" +
		  "\u001B.(;\u001B.I81;;17:\u001B.N;19:IN;;\n" +
		  "  ;Preset common settings;\n" +
                  "AP;LT;VS18;FS50;\n" +
		  "  ;Plot area and scaling;\n" +
                  "IP;SC;\n" +
		  "  ;User defined pre settings;\n" +
		  "SP1;PU;\n\n" +
		  "  ;Toolpaths:;\n" 

    // ===PLT-FILE-FOOTER=================================================
    // >>> Store pen, View workpiece, go Off line. <<<		  
    // PU;PA0,0;        ; Pen Up, goto 0,0
    // SP;              ; Store Pen, preventing drying out.
    // NR;              ; Not Ready, Offline View Mode,
    //                  ; (Carriage and workpiece to view-position,  )
    //                  ; (Off Line prevents next file to be plotted.)
    // EC;              ; Gerber Interactive! Enable Cutter. HPGL/2.
    // PG1;             ; Gerber Interactive!
    // OE;              ; Gerber Interactive! Output Error to application. Gerber.
    // TD;              ; Gerber interactive! Tool Drill; switch from router to drill.
    //                  ;
    // Esc.)            ; Switch Com-port off, or
    // Esc.Z            ; Plotter Off; same as Esc.)
    //                  ;
    // Original QCAD:
    // this.footer = "PA0,0;SP;EC;PG1;EC1;OE;";
    //                  ; First line	; Pen Up, Home pen, Unload carriage,
    //                  ; Second line	; Gerber Interactive!
    //			; Third line	; View mode, plotter off line.
    this.footer = "\n" +
                  "  ;Store pen, View, Off line;\n" +   
                  "PU;PA0,0;SP;\n" +
//                  "EC;PG1;EC1;OE" +
                  "NR;\u001B.);\n"; 

     
    // ===PLT-BODY================================================================================
    //                  ; (All coordinates are in plu, unless a user unit is set.)  
    // PA X, Y;         ; Point Absolute.  Goto absolute coord.
    // SP1;             ; Select Pen 1 (1...8)
    // PD;              ; Pen Down.  (Z down movement at Plunge Rate replaced by PD-command)
    // AA X, Y, Angle	; Arc Absolute.
    //                  ; Startpoint = current position.
    //                  ; X,Y = arc Center coords
    //                  ; Angle = in decimal degrees (integers?)
    //                  ;         Pos. Angle = CCW
    //                  ;         Neg. Angle = CW
    // CI r,c           ; Circle.  Draw a circle; Center at current position,
    //                  ; r = radius, startpoint 0 degrees (neg radius = startpoint 180) 
    //                  ; c = chord tolerance, see CT.
    // [T]              ; = STRVAL([toolvalue])
    // [T!]             ; = 1e point?
    // [T#!]            ; = 2e point?
    // %                ; = comment, not executed (might sometimes be needed)

	
    // >>Header/footer before/after tool change:<<<
    // Tool/Pen change, Set speed (Velocity, Feed Rate), Set force (Spindle Speed S)
    this.toolHeader = "SP[T];VS[F],[T];FS[S],[T]" + this.separator;
    this.toolFooter = [];
        
    // PA = Plot Absolute
    this.linearMove = "PA[X],[Y]" + this.separator;
    this.firstLinearMove = this.linearMove;
    
    // AA = Arc Absolute clockwise
    this.arcCWMove = "AA[IA],[JA],[SWEEP]" + this.separator;
    this.firstArcCWMove = this.arcCWMove;

    // AA = Arc Absolute counter clockwise
    this.arcCCWMove = "AA[IA],[JA],[SWEEP]" + this.separator;
    this.firstArcCCWMove = this.arcCCWMove;
    
    // PA = Plot Absolute, on coordinate
    // PD = Pen Down
    this.zPassHeader = "PA[X1],[Y1]" + this.separator + "PD" + this.separator;
    this.zPassFirstHeader = this.zPassHeader;

    // PU = Pen Up (after previous movements) + 
    // Start next toolpath on new line (\n)
    this.zPassFooter = "PU" + this.separator + "\n";
    this.zPassLastFooter = this.zPassFooter;
}

HPPenPlotter.prototype = new CamExporterV2();
HPPenPlotter.displayName = "HP Pen Plotter";


