package jgrasp_viewers_python;


import java.util.ArrayList;
import java.util.List;
import jgrasp.PluginOptOut;
import jgrasp.viewer.Util;
import jgrasp.viewer.ViewerCreateData;
import jgrasp.viewer.ViewerException;
import jgrasp.viewer.ViewerInfo;
import jgrasp.viewer.ViewerValueData;
import jgrasp.viewer.jgrdi.DebugContext;
import jgrasp.viewer.jgrdi.Value;
import jgrasp.viewer.presentation.PresentationListView;


/** Presentation viewer for java.util.ArrayList. **/
public class _X_PresentationElementsView extends PresentationListView {

   /** The per-class settings. **/
   private static Settings perClassSettings;


   /** Creates a new presentation ArrayList viewer.
    *
    * @param vcd creation data. **/
   public _X_PresentationElementsView(final ViewerCreateData vcd) {
      super(vcd, 0);
      if (!vcd.getValue().isArray(vcd.getDebugContext())) {
         throw new PluginOptOut();
      }
   }


   /** {@inheritDoc} **/
   @Override
   public List<ListElementData> getElements(final Value value, final int offset, final int len,
         final DebugContext context) throws ViewerException {
      List<ListElementData> result = new ArrayList<>();
      for (Value v : value.getArrayElements(context, offset, len)) {
         result.add(new ListElementData(v, null, true));
      }
      return result;
   }


   /** {@inheritDoc} **/
   @Override
   public int getFullLimit() {
      return 50;
   }


   /** {@inheritDoc} **/
   @Override
   public void getInfo(final ViewerInfo vi) {
      vi.setShortDescription("Presentation viewer for list-like objects");
      vi.setLongDescription("This viewer displays the elements of list-like object. The string values of "
            + "the elements are displayed in the nodes. Selecting an element will cause its value to be displayed in "
            + "a subviewer.");
   }


   /** {@inheritDoc} **/
   @Override
   public String getLeftIndexMarker(final ViewerValueData valueData, final DebugContext context) {
      if (valueData.value().isInstanceOf(context, "builtins.list")
            || valueData.value().isInstanceOf(context, "builtins.tuple")) {
         return "[";
      }
      return "<";
   }


   /** {@inheritDoc} **/
   @Override
   public String getRightIndexMarker(final ViewerValueData valueData, final DebugContext context) {
      if (valueData.value().isInstanceOf(context, "builtins.list")
            || valueData.value().isInstanceOf(context, "builtins.tuple")) {
         return "]";
      }
      return ">";
   }


   /** {@inheritDoc} **/
   @Override
   public int getLength(final Value value, final DebugContext context) throws ViewerException {
      return value.getArrayLength(context);
   }


   /** {@inheritDoc} **/
   @Override
   protected Settings getPerClassSettings() {
      if (perClassSettings == null) {
         perClassSettings = createGlobalSettings();
      }
      return perClassSettings;
   }


   /** {@inheritDoc} **/
   @Override
   public boolean isObjectList(final Value value, final DebugContext context) {
      return true;
   }


   /** Gets the expression for a value at a specified index.
    *
    * @param valueData the value update data.
    *
    * @param index the index of interest.
    *
    * @return an expression for the value at the requested index, or null if there is no expression for the current
    * value. The default creates a method call expression if the subclass provides a method and required type. **/
   @Override
   public String getExpr(final ViewerValueData valueData, final int index, final DebugContext context) {
      return Util.getPythonExpr(getVIData(), valueData, index, context);
   }
}
