<?xml version="1.0" encoding="utf-8"?>
<!--
Each type="form" subtree is an API and has a flat, _ordered_ list of fields.
Each field may have the following properties:
  type: integer, enum, mm, string, enum:country:code, enum:country:name
  note: human readable explanation of what the field is for
  default: default value to present when it is not already specified/derived
  group: fields may form of topic groups by matching group name

When type is "enum", the node will have <Value> children listing all possible
values. If there is no "default" specified, use the first <Value>.

Types enum:country:code and enum:country:name are enums whose values are
loaded from the list acquired using the api/Address/GetCountry API.
-->
<PCBWayAPI>
    <PcbQuotationRequest type="form" note="PCB quote interface" path="api/Pcb/PcbQuotation">
        <boardWidth group="pcb" type="mm" default="100" note="Board width"></boardWidth>
        <boardHeight group="pcb" type="mm" default="100" note="board height"></boardHeight>
        <boardLayer group="pcb" type="enum" default="2" note="Number of copper layers">
            <Value>1</Value>
            <Value>2</Value>
            <Value>4</Value>
            <Value>6</Value>
            <Value>8</Value>
            <Value>10</Value>
            <Value>12</Value>
            <Value>14</Value>
        </boardLayer>
        <DesignInPanel group="pcb" type="integer" default="1" note="Number of different designs in the panel"></DesignInPanel>
        <FR4Tg type="enum" default="TG150" note="Laminate glass transition temperature">
            <Value>TG130</Value>
            <Value>TG150</Value>
            <Value>TG170</Value>
            <Value>S1000H TG150</Value>
        </FR4Tg>
        <Thickness group="pcb" type="enum" default="1.6" note="Final board thickness in mm">
            <Value>0.2</Value>
            <Value>0.3</Value>
            <Value>0.4</Value>
            <Value>0.6</Value>
            <Value>0.8</Value>
            <Value>1.0</Value>
            <Value>1.2</Value>
            <Value>1.6</Value>
            <Value>2.0</Value>
            <Value>2.4</Value>
            <Value>2.6</Value>
            <Value>2.8</Value>
            <Value>3.0</Value>
            <Value>3.2</Value>
        </Thickness>
        <FinishedCopper group="pcb" type="enum" default="1" note="Finished copper thickness in oz Cu">
            <Value>0</Value>
            <Value>1</Value>
            <Value>2</Value>
            <Value>3</Value>
            <Value>4</Value>
            <Value>5</Value>
            <Value>6</Value>
            <Value>7</Value>
            <Value>8</Value>
            <Value>9</Value>
            <Value>10</Value>
            <Value>11</Value>
            <Value>12</Value>
            <Value>13</Value>
        </FinishedCopper>
        <Material group="pcb" type="enum" default="FR-4" note="Substrate material">
            <Value>FR-4</Value>
            <Value>Aluminum board</Value>
            <Value>Rogers</Value>
            <Value>HDI</Value>
            <Value>Copper</Value>
        </Material>
        <MinHoleSize group="pcb" type="enum" default="0.3" note="Diameter of the smallest hole, mm">
            <Value>0.15</Value>
            <Value>0.2</Value>
            <Value>0.25</Value>
            <Value>0.3</Value>
            <Value>0.8</Value>
            <Value>1.0</Value>
            <Value>-1</Value>
        </MinHoleSize>
        <MinTrackSpacing group="pcb" type="enum" default="6/6mil" note="Track width/clearance">
            <Value>3/3mil</Value>
            <Value>4/4mil</Value>
            <Value>5/5mil</Value>
            <Value>6/6mil</Value>
            <Value>8/8mil</Value>
        </MinTrackSpacing>
        <Qty group="pcb" type="enum" default="5" note="Number of copies to be fabricated">
            <Value>5</Value>
            <Value>10</Value>
            <Value>15</Value>
            <Value>20</Value>
            <Value>25</Value>
            <Value>30</Value>
            <Value>40</Value>
            <Value>50</Value>
            <Value>75</Value>
            <Value>100</Value>
            <Value>125</Value>
            <Value>150</Value>
            <Value>200</Value>
            <Value>250</Value>
            <Value>300</Value>
            <Value>350</Value>
            <Value>400</Value>
            <Value>450</Value>
            <Value>500</Value>
            <Value>600</Value>
            <Value>700</Value>
            <Value>800</Value>
            <Value>900</Value>
            <Value>1000</Value>
            <Value>1500</Value>
            <Value>2000</Value>
            <Value>2500</Value>
            <Value>3000</Value>
            <Value>3500</Value>
            <Value>4000</Value>
            <Value>4500</Value>
            <Value>5000</Value>
            <Value>5500</Value>
            <Value>6000</Value>
            <Value>6500</Value>
            <Value>7000</Value>
            <Value>7500</Value>
            <Value>8000</Value>
            <Value>9000</Value>
            <Value>10000</Value>
        </Qty>
        <SolderMask group="pcb" type="enum" default="Green" note="Color of the solder mask">
            <Value>Green</Value>
            <Value>Red</Value>
            <Value>Yellow</Value>
            <Value>Blue</Value>
            <Value>White</Value>
            <Value>Black</Value>
            <Value>Purple</Value>
            <Value>Matt black</Value>
            <Value>Matt green</Value>
            <Value>None</Value>
        </SolderMask>
        <Silkscreen group="pcb" type="enum" default="White" note="Color of the silkscreen graphics">
            <Value>White</Value>
            <Value>Black</Value>
            <Value>None</Value>
        </Silkscreen>
        <SurfaceFinish group="pcb" default="HASL with lead" type="enum">
            <Value>HASL with lead</Value>
            <Value>HASL lead free</Value>
            <Value>Immersion gold</Value>
            <Value>Hard Gold</Value>
            <Value>OSP</Value>
            <Value>Immersion Silver</Value>
            <Value>ENEPIG</Value>
            <Value>None</Value>
        </SurfaceFinish>
        <ViaProcess group="pcb" type="enum" default="Tenting vias" note="Ignored when uploading gerbers: vias are made as specified in the gerbers.">
            <Value>Tenting vias</Value>
            <Value>Plugged vias</Value>
            <Value>Vias not covered</Value>
        </ViaProcess>
        <Goldfingers group="pcb" type="enum" default="No" note="Whether to apply gold finish on edge connector fingers">
            <Value>Yes</Value>
            <Value>No</Value>
        </Goldfingers>
    </PcbQuotationRequest>

<!--
The constraint scripting language is a small Domain Specific Language
designed to verify form data before submitting an order.

Data types are: integer, float, string. When converting to boolean,
numeric value 0 means false, anything else means true; a string is false
if it is empty, else it is true.

The script is an ordered sequence of statements. A statement is one of:
- if (expr) statement
- error(varname, explanation);
- {} block (multiple statements wrapped in curly braces)

An expression is:
- a constant
- a variable
- parenthesis to change precedence: (expr)
- logical and: expr && expr
- logical or: expr || expr
- logical not: !expr
- equality comparison (numbers and strings):
  - equal: expr == expr
  - not equal: expr != expr
- arithmetic comparison (numbers only):
  - greater than: expr > expr
  - greater than or equal: expr >= expr
  - less than: expr < expr
  - less than or equal: expr <= expr
- arithmetic operators (numbers only):
  - numeric negation: - expr
  - addition: expr + expr
  - subtraction: expr - expr
  - multiplication: expr / expr
  - modulo: expr % expr
- explicit type conversion:
  - convert to integer: int(expr)
  - convert to float: float(expr)
  - convert to string: string(expr)

Constants:
- a decimal integer
- a decimal floating point number
- a string in double quotes, e.g. "foo"

Variables are $fieldname, where fieldname is a case sensitive field
name from the form.

Logic operations result in an integer, 0 or 1. Numbers are converted to
float for arithmetic operations. When any of the operands of an equality
operator is a string, both operands are converted to string. String
equality is case sensitive.

When a string is given to the explicit numerical conversions int() and
float(), they convert the leading sequence of characters as long as a
valid number is detected and ignore the rest of the string. If there is
no valid leading numeric, 0 is returned. For example "19 oz copper" is
converted to 19 (or 19.0) and "no copper" is converted to 0.

Error()'s first argument is a variable name without $ or double-quote. The
second argument is always a double quoted string. $variables are
evaluated to int, float or string, depending on field type; enum fields
are always evaluated to (enum value) strings.
-->
    <PcbQuotationConstraints type="constraints">
        <![CDATA[
        if (($Material == "Aluminum board") || ($Material == "Copper")) {
            if ((int($boardLayer) != 1) && (int($boardLayer) != 2))
                error(boardLayer, "Aluminium/copper board must have 1 or 2 layers");
            if (float($Thickness) <= 0.3)
                error(Thickness, "Aluminium/copper board must be thicker than 0.3mm");
            if (int($MinTrackSpacing) < 4)
                error(MinTrackSpacing, "Minimum track spacing must be at least 4/4");
            if ((int($boardLayer) == 1) && (float($MinHoleSize) < 0.8))
                error(MinHoleSize, "1-layer metal core board holes must be at least 0.8mm in diameter");
            if ((int($boardLayer) == 2) && (float($MinHoleSize) < 0.2))
                error(MinHoleSize, "2-layer metal core board holes must be at least 0.2mm in diameter");
            if ((int($MinTrackSpacing) == 4) || (int($MinTrackSpacing) == 5)) {
                if (int($FinishedCopper) != 1)
                    error(FinishedCopper, "Aluminum/copper board with 4/4 or 5/5 spacing must have finished copper 1 oz Cu");
            }
            if (int($MinTrackSpacing) == 6) {
                if ((int($FinishedCopper) != 1) && (int($FinishedCopper) != 2))
                    error(FinishedCopper, "Aluminum/copper board with 6/6 spacing must have finished copper 1 or 2 oz Cu");
            }
            if (int($MinTrackSpacing) == 8) {
                if ((int($FinishedCopper) != 1) && (int($FinishedCopper) != 2) && (int($FinishedCopper) != 3) && (int($FinishedCopper) != 4))
                    error(FinishedCopper, "Aluminum/copper board with 8/8 spacing must have finished copper 1, 2, 3 or 4 oz Cu");
            }
        }

        if ($Material == "FR-4") {
            if (int($boardLayer) == 4) {
                if ((float($Thickness) < 0.4) || (float($Thickness) > 3.2))
                   error(Thickness, "4-layer FR4 board must be between 0.4 and 3.2 in thickness");
            }
            if (int($boardLayer) == 6) {
                if ((float($Thickness) < 0.8) || (float($Thickness) > 3.2))
                   error(Thickness, "6-layer FR4 board must be between 0.8 and 3.2 in thickness");
            }
            if (int($boardLayer) == 8) {
                if ((float($Thickness) < 1.0) || (float($Thickness) > 3.2))
                   error(Thickness, "8-layer FR4 board must be between 1.0 and 3.2 in thickness");
            }
            if (int($boardLayer) == 10) {
                if ((float($Thickness) < 1.2) || (float($Thickness) > 3.2))
                   error(Thickness, "10-layer FR4 board must be between 1.2 and 3.2 in thickness");
            }
            if (int($boardLayer) == 12) {
                if ((float($Thickness) < 1.6) || (float($Thickness) > 3.2))
                   error(Thickness, "12-layer FR4 board must be between 1.6 and 3.2 in thickness");
            }
            if (int($boardLayer) == 14) {
                if ((float($Thickness) < 2.0) || (float($Thickness) > 3.2))
                   error(Thickness, "14-layer FR4 board must be between 2.0 and 3.2 in thickness");
            }
            if ((float($MinHoleSize) < 0.15) || (float($MinHoleSize) > 0.3)) {
                error(MinHoleSize, "Mininum hole size on FR-4 must be between 0.15 and 0.3");
            }
            if ((int($MinTrackSpacing) == 3) || (int($MinTrackSpacing) == 4) || (int($MinTrackSpacing) == 5)) {
                if (int($FinishedCopper) != 1)
                    error(FinishedCopper, "FR4 board with 3/3 or 4/4 or 5/5 spacing must have finished copper 1 oz Cu");
            }
            if (int($MinTrackSpacing) == 6) {
                if ((int($FinishedCopper) != 1) && (int($FinishedCopper) != 2))
                    error(FinishedCopper, "FR4 board with 6/6 spacing must have finished copper 1 or 2 oz Cu");
            }
            if (int($MinTrackSpacing) == 8) {
                if ((int($FinishedCopper) < 1) && (int($FinishedCopper) > 13))
                    error(FinishedCopper, "FR4 board with 8/8 spacing must have finished copper between 1 and 13 oz Cu");
            }
        }

        if ($Silkscreen == "Black") {
            if (($SolderMask == "Red") || ($SolderMask == "Blue") || ($SolderMask == "Black") || ($SolderMask == "Purple") || ($SolderMask == "Matt black") || ($SolderMask == "Matt green"))
                error(Silkscreen, "Invalid SilkScreen/soldermask color combination with. Please choose White for SilkScreen!");
        }
        if ($Silkscreen == "White") {
            if ($SolderMask == "White")
                error(Silkscreen, "Invalid SilkScreen/soldermask color combination with. Please choose Black for SilkScreen!");
        }
        if (float($Thickness) < 0.6) {
            if (($SurfaceFinish == "HASL with lead") || ($SurfaceFinish == "HASL lead free"))
                error(Thickness, "Board must be at least 0.6mm thick for HASL finish. Select a thicker board or a different finish!");
        }
        ]]>
    </PcbQuotationConstraints>
</PCBWayAPI>

