/*
 * The MIT License
 *
 * Copyright 2016 gburdell.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package laol.ast;

import apfe.runtime.Acceptor;
import apfe.runtime.Sequence;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * @author gburdell
 */
public class PostfixExpression extends Item {

    public PostfixExpression(final laol.parser.apfe.PostfixExpression decl) {
        super(decl);
        Item expr;
        for (Acceptor ele : decl.getItems()) {
            if (ele instanceof Sequence) {
                final Sequence seq = asSequence(ele);
                final Acceptor first = seq.getAccepted()[0];
                if (first instanceof laol.parser.apfe.LBRACK) {
                    expr = new ArySelExpr(seq);
                } else if (first instanceof laol.parser.apfe.LPAREN) {
                    expr = new PrimExprList(seq);
                } else if (first instanceof laol.parser.apfe.DotSuffix) {
                    expr = new DotSfx(seq);
                } else {
                    expr = new PrimExpr(seq);
                }
            } else {
                expr = new IncDec(ele);
            }
            m_exprs.add(expr);
        }
    }

    public static class ItemWithBlock extends Item {
        
        protected ItemWithBlock(Acceptor parsed) {
            super(parsed);
            m_seq = asSequence();
            final int n = m_seq.getAccepted().length - 1;
            m_block = oneOrNone(m_seq, n);
        }

        public Block getBlock() {
            return m_block;
        }
        
        protected final Sequence m_seq;
        
        private final Block m_block;
    }
    
    public static class ArySelExpr extends ItemWithBlock {

        private ArySelExpr(Acceptor parsed) {
            super(parsed);
            m_expr = createItem(m_seq, 1);
        }

        public ArraySelectExpression getExpr() {
            return m_expr;
        }
        
        private final ArraySelectExpression m_expr;
    }

    public static class PrimExprList extends ItemWithBlock {

        private PrimExprList(Acceptor parsed) {
            super(parsed);
            m_expr = oneOrNone(m_seq, 1);
        }

        public ParamExpressionList getExpr() {
            return m_expr;
        }        
        
        private ParamExpressionList m_expr;
    }

    public static class DotSfx extends ItemWithBlock {

        private DotSfx(Acceptor parsed) {
            super(parsed);
            m_expr = createItem(m_seq, 0);
        }

        public DotSuffix getExpr() {
            return m_expr;
        }
    
        private final DotSuffix   m_expr;
    }

    public static class IncDec extends Keyword {

        private IncDec(Acceptor parsed) {
            super(parsed.getBaseAccepted());
        }
    }

    public static class PrimExpr extends ItemWithBlock {

        private PrimExpr(Acceptor parsed) {
            super(parsed);
            m_expr = createItem(m_seq, 0);
        }

        public PrimaryExpression getExpr() {
            return m_expr;
        }
        
        private final PrimaryExpression m_expr;
    }

    public List<Item> getExprs() {
        return Collections.unmodifiableList(m_exprs);
    }

    private final List<Item>  m_exprs = new LinkedList<>();
}

@@ -1534,55 +1534,8 @@
 ) %7B%0A
-            if (ele instanceof Sequence) %7B%0A    
     
@@ -1576,28 +1576,24 @@
 uence(ele);%0A
-    
             
@@ -1623,30 +1623,19 @@
 seq.
-getAccepted()%5B0%5D;%0A    
+itemAt(0);%0A
     
@@ -1698,36 +1698,32 @@
                 
-    
 expr = new ArySe
@@ -1738,36 +1738,32 @@
 q);%0A            
-  
-  
 %7D else if (first
@@ -1809,36 +1809,32 @@
                 
-    
 expr = new PrimE
@@ -1851,36 +1851,32 @@
 q);%0A            
- 
-   
 %7D else if (first
@@ -1925,36 +1925,32 @@
                 
-   
- 
 expr = new DotSf
@@ -1969,33 +1969,82 @@
         
-    %7D else %7B%0A    
+%7D else if (first instanceof laol.parser.apfe.PrimaryExpression) %7B%0A
         
@@ -2093,34 +2093,60 @@
     
-    %7D%0A            %7D else %7B
+%7D else %7B%0A                assert (1 == seq.length());
 %0A   
@@ -2176,19 +2176,29 @@
  IncDec(
-ele
+seq.itemAt(0)
 );%0A     
@@ -2307,24 +2307,16 @@
  Item %7B%0A
-        
 %0A       
@@ -2600,32 +2600,24 @@
 ;%0A        %7D%0A
-        
 %0A        pro
@@ -2645,24 +2645,16 @@
  m_seq;%0A
-        
 %0A       
@@ -2685,28 +2685,24 @@
 lock;%0A    %7D%0A
-    
 %0A    public 
@@ -2959,32 +2959,24 @@
 ;%0A        %7D%0A
-        
 %0A        pri
@@ -3296,33 +3296,17 @@
        %7D
-        %0A        
+%0A
 %0A       
@@ -3602,20 +3602,16 @@
       %7D%0A
-    
 %0A       
@@ -3635,18 +3635,16 @@
 tSuffix 
-  
 m_expr;%0A
@@ -3764,22 +3764,39 @@
 per(
+asPrioritizedChoice(
 parsed
+)
 .get
-Base
 Acce
@@ -4086,24 +4086,16 @@
       %7D%0A
-        
 %0A       
@@ -4266,17 +4266,16 @@
 st%3CItem%3E
- 
  m_exprs

fix AST. GrammarTest fail remains.