// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.debug.core.model;

import java.util.Collections;
import java.util.Set;

import org.chromium.sdk.JsArray;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IIndexedValue;
import org.eclipse.debug.core.model.IVariable;

/**
 * An IIndexedValue implementation for an array element range using a JsArray
 * instance.
 */
public class ArrayValue extends Value implements IIndexedValue {

  private final IVariable[] elements;

  public ArrayValue(DebugTargetImpl debugTarget, JsArray array) {
    super(debugTarget, array);
    this.elements = createElements();
  }

  private IVariable[] createElements() {
    JsArray jsArray = (JsArray) getJsValue();
    return StackFrame.wrapVariables(getDebugTarget(), jsArray.getProperties(),
        ARRAY_HIDDEN_PROPERTY_NAMES,
        // Do not show internal properties for arrays (this may be an option).
        null);
  }

  public int getInitialOffset() {
    return 0;
  }

  public int getSize() throws DebugException {
    return elements.length;
  }

  public IVariable getVariable(int offset) throws DebugException {
    return elements[offset];
  }

  public IVariable[] getVariables(int offset, int length) throws DebugException {
    IVariable[] result = new IVariable[length];
    System.arraycopy(elements, offset, result, 0, length);
    return result;
  }

  @Override
  public IVariable[] getVariables() throws DebugException {
    return elements;
  }

  @Override
  public boolean hasVariables() throws DebugException {
    return elements.length > 0;
  }

  private static final Set<String> ARRAY_HIDDEN_PROPERTY_NAMES = Collections.singleton("length");
}

@@ -254,16 +254,68 @@
 til.Set;
+%0Aimport java.util.concurrent.atomic.AtomicReference;
 %0A%0Aimport
@@ -667,16 +667,32 @@
 e final 
+AtomicReference%3C
 IVariabl
@@ -694,16 +694,17 @@
 riable%5B%5D
+%3E
  element
@@ -704,16 +704,60 @@
 elements
+Ref = new AtomicReference%3CIVariable%5B%5D%3E(null)
 ;%0A%0A  pub
@@ -852,46 +852,8 @@
 y);%0A
-    this.elements = createElements();%0A
   %7D%0A
@@ -1151,24 +1151,289 @@
 null);%0A  %7D%0A%0A
+  private IVariable%5B%5D getElements() %7B%0A    IVariable%5B%5D result = elementsRef.get();%0A    if (result == null) %7B%0A      result = createElements();%0A      elementsRef.compareAndSet(null, result);%0A      return elementsRef.get();%0A    %7D else %7B%0A      return result;%0A    %7D%0A  %7D%0A%0A
   public int
@@ -1527,32 +1527,37 @@
 %0A    return 
-e
+getE
 lements
+()
 .length;%0A  %7D
@@ -1636,24 +1636,29 @@
  return 
-e
+getE
 lements
+()
 %5Boffset%5D
@@ -1815,24 +1815,29 @@
 raycopy(
-e
+getE
 lements
+()
 , offset
@@ -1965,24 +1965,29 @@
  return 
-e
+getE
 lements
+()
 ;%0A  %7D%0A%0A 
@@ -2064,24 +2064,29 @@
  return 
-e
+getE
 lements
+()
 .length 

Load array elements asynchronously (or may cause deadlock)