<%@page contentType="text/html;charset=UTF-8" pageEncoding="ISO-8859-1" session="true"
%><%@page errorPage="Exception.jsp"
%><%@page import="com.fujitsu.iflow.common.UdaNameSanitizer"
%><%@page import="com.fujitsu.iflow.model.bpm.BPMSession"
%><%@page import="com.fujitsu.iflow.model.util.QuickForm"
%><%@page import="com.fujitsu.iflow.model.util.QuickFormOperation"
%><%@page import="com.fujitsu.iflow.model.util.URLEncoder"
%><%@page import="com.fujitsu.iflow.model.workflow.Arrow"
%><%@page import="com.fujitsu.iflow.model.workflow.DataItem"
%><%@page import="com.fujitsu.iflow.model.workflow.FormRef"
%><%@page import="com.fujitsu.iflow.model.workflow.Node"
%><%@page import="com.fujitsu.iflow.model.workflow.NodeInstance"
%><%@page import="com.fujitsu.iflow.model.workflow.Plan"
%><%@page import="com.fujitsu.iflow.model.workflow.ProcessInstance"
%><%@page import="com.fujitsu.iflow.model.workflow.WFObjectFactory"
%><%@page import="com.fujitsu.iflow.model.workflow.WorkItem"
%><%@page import="java.awt.Point"
%><%@page import="java.io.File"
%><%@page import="java.io.PrintWriter"
%><%@page import="java.io.Writer"
%><%@page import="java.lang.Long"

%><%@page import="java.net.URL"
%><%@page import="java.text.ParseException"
%><%@page import="java.text.DateFormat"
%><%@page import="java.util.Date"
%><%@page import="java.util.Hashtable"
%><%@page import="java.util.Locale"
%><%
    request.setCharacterEncoding("UTF-8");request.getParameterNames(); //Need dummy call for WL9.1
    BPMSession bps = (BPMSession) session.getAttribute("BPMSession");
    if (bps == null) {
        %><jsp:include page="PasswordPanel.jsp" flush="true"/><%
        return;
    }

    // change this variable if you save this file to a new name.
    String nameOfThisPage = "EditPD.jsp";

    String pdIdStr = request.getParameter("pdId");
    if (pdIdStr == null) {
        throw new Exception(nameOfThisPage + " needs a pdId parameter to tell it which process definition to work on.");
    }

    long piId = 0;
    try {
        piId = Long.parseLong(pdIdStr);
    }
    catch (Exception e) {
        throw new Exception(nameOfThisPage + " pdId parameter must be an integer value instead of ("+pdIdStr+")");
    }

    Plan plan = bps.getPlan(piId);
    boolean isEdit = plan.isInEditMode();

    String mode = request.getParameter("mode");
    String aux = request.getParameter("aux");
    String nodeStr = request.getParameter("node");
    String arrowStr = request.getParameter("arrow");

    try {

        if (mode == null) {
            throw new Exception("This page requires a 'mode' parameter");
        }

        String newValue = request.getParameter("newValue");
        if (newValue == null) {
            throw new Exception(nameOfThisPage + " needs a 'newValue' parameter to hold the value to change to.");
        }

        if (!isEdit) {
            throw new Exception("Unable to update the '"+mode+"' because Process Definition is not in edit mode anymore.");
        }

        try {
            if (mode.equals("name")) {
                plan.setName(newValue);
            }
            else if (mode.equals("desc")) {
                plan.setDesc(newValue);
            }
            else if (mode.equals("title")) {
                plan.setTitle(newValue);
            }
            else if (mode.equals("iden")) {
                plan.setPlanIdentifier(newValue);
            }
            else if (mode.equals("oscript")) {
                plan.setProcOwnerRoleScript(newValue);
            }
            else if (mode.equals("init")) {
                plan.setInitScript(newValue);
            }
            else if (mode.equals("commit")) {
                plan.setCommitScript(newValue);
            }
            else if (mode.equals("nname")) {
                getNode(plan,nodeStr).setName(newValue);
            }
            else if (mode.equals("ndesc")) {
                getNode(plan,nodeStr).setDesc(newValue);
            }
            else if (mode.equals("role")) {
                getNode(plan,nodeStr).setRole(newValue);
            }
            else if (mode.equals("npos")) {
                setNodePosition(getNode(plan,nodeStr), newValue);
            }
            else if (mode.equals("rscript")) {
                getNode(plan,nodeStr).setRoleScript(newValue);
            }
            else if (mode.equals("prol")) {
                getNode(plan,nodeStr).setPrologueScript(newValue);
            }
            else if (mode.equals("epil")) {
                getNode(plan,nodeStr).setEpilogueScript(newValue);
            }
            else if (mode.equals("aname")) {
                getArrow(plan,arrowStr).setName(newValue);
            }
            else if (mode.equals("points")) {
                setArrowPosition(getArrow(plan,arrowStr), newValue);
            }
            else if (mode.equals("fpath")) {
                getNodeForm(getNode(plan,nodeStr), aux).setPath(newValue);
            }
            else if (mode.equals("fname")) {
                getNodeForm(getNode(plan,nodeStr), aux).setName(newValue);
            }
            else {
                throw new Exception("The mode '"+mode+"' is not supported at this time.");
            }
        }
        catch (Exception e) {
            throw new Exception("Unable to handle  mode '"+mode+"' request.", e);
        }

        // This is in the iframe window
        response.sendRedirect("ProcessDefinition.jsp?planID=" + pdIdStr);

    }
    catch (Exception e) {
        throw new Exception ("Unable to render form '"+nameOfThisPage+
               "' for work item (id="+pdIdStr+") because: "+e.getMessage());
    }

%>

<%!

public Node getNode(Plan plan,String nodeStr) throws Exception
{
    if (nodeStr == null) {
        throw new Exception("Needs a 'node' parameter.");
    }
    long nodeId = safeParseInt(nodeStr);
    Node node = plan.getNode(nodeId);
    if (node == null) {
        throw new Exception("Can't find a node with id = '"+nodeStr+"'.");
    }
    return node;
}

public Arrow getArrow(Plan plan,String arrowStr) throws Exception
{
    if (arrowStr == null) {
        throw new Exception("Needs a 'arrow' parameter.");
    }
    long arrowId = safeParseInt(arrowStr);
    Arrow arrow = plan.getArrow(arrowId);
    if (arrow == null) {
        throw new Exception("Can't find an arrow with id = '"+arrowStr+"'.");
    }
    return arrow;
}


public FormRef getNodeForm(Node node, String aux) throws Exception
{
    if (aux == null)  {
        throw new Exception("needs an 'aux' parameter.");
    }
    int auxInt = safeParseInt(aux);
    FormRef[] forms = node.getForms();
    if (forms == null) {
        throw new Exception("Got a null back from getForms.  Process Instance has probably been changed recently.");
    }
    if (auxInt < 0 || auxInt >= forms.length) {
        throw new Exception("'aux' parameter value must be the index to the form, between zero and "+forms.length);
    }
    return forms[auxInt];
}


public int safeParseInt(String val) throws Exception
{
    try {
        int intVal = Integer.parseInt(val);
        return intVal;
    }
    catch (Exception e) {
        throw new Exception("Not able to parse an integer value from '"+val+"'");
    }
}

public
void
setNodePosition(Node node, String newValue)
    throws Exception
{
    try {
        Point aPoint = new Point();
        int pos = newValue.indexOf('(');
        if (pos < 0) {
            throw new Exception("it must start with an open parenthesis.");
        }
        pos = newValue.indexOf(',');
        if (pos < 2) {
            throw new Exception("it must have a number followed by a comma character; e.g. it must be something like '(50,50)'");
        }
        int oldPos = pos+1;
        pos = newValue.indexOf(')', oldPos);
        if (pos < 4) {
            throw new Exception("it must have a second number followed by a closing paren; e.g. it must be something like '(50,50)'");
        }
        aPoint.x = parseInt(newValue, 1, oldPos);
        aPoint.y = parseInt(newValue, oldPos, pos);

        node.setPosition(aPoint);
    }
    catch (Exception e) {
        throw new Exception("Unable to parse the position value '"+newValue+"' ("+e.toString()+")");
    }
}


public
void
setArrowPosition(Arrow arrow, String newValue)
    throws Exception
{
    try {
        Point aPoint = new Point();
        Point[] pointBuf = new Point[20];
        int pos = 0;
        int sPos = 0;
        int middlePointCount = 0;
        boolean atStart = true;
        boolean isMore = true;

        while (isMore) {

            pos = newValue.indexOf('(', sPos);
            if (pos < sPos) {
                throw new Exception("it must start with an open parenthesis.");
            }
            sPos = pos;
            pos = newValue.indexOf(',', sPos);
            if (pos < sPos) {
                throw new Exception("it must have a number followed by a comma character; e.g. it must be something like '(50,50)'");
            }
            aPoint.x = parseInt(newValue, sPos, pos);
            sPos = pos+1;
            pos = newValue.indexOf(')', sPos);
            if (pos < sPos) {
                throw new Exception("it must have a second number followed by a closing paren; e.g. it must be something like '(50,50)'");
            }
            aPoint.y = parseInt(newValue, sPos, pos);
            sPos = pos;
            pos = newValue.indexOf(';', sPos);
            isMore = (pos > sPos);

            if (!isMore) {
                if (atStart) {
                    throw new Exception("must be at least two point values in parenthesis, and they must be separated by a semicolon");
                }
                arrow.setEndPoint(aPoint);
            }
            else if (atStart) {
                arrow.setStartPoint(aPoint);
                atStart = false;
            }
            else {
                pointBuf[middlePointCount] = new Point(aPoint.x, aPoint.y);
                middlePointCount++;
            }
        }


        if (middlePointCount>0) {
            Point[] finalSet = new Point[middlePointCount];
            for (int i=0; i<middlePointCount; i++) {
                finalSet[i] = pointBuf[i];
            }
            arrow.setPoints(finalSet);
        }
    }
    catch (Exception e) {
        throw new Exception("Unable to parse the position value '"+newValue+"' ("+e.toString()+")");
    }
}




// Basic parse int routine from middle of string
// ignore non numeric characters
// all digits in string count, regardless of intervening garbage
// does not handle negatives.
public
int
parseInt(String inStr, int sPos, int ePos)
{
    int val = 0;
    for (int i=sPos; i<ePos; i++) {
        char ch = inStr.charAt(i);
        if (ch >= '0' && ch <= '9') {
            val = val*10 + (int)(ch) - 48;
        }
    }
    return val;
}

%>

