package com.integreight.onesheeld.utils.customviews;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.integreight.onesheeld.R;
import com.integreight.onesheeld.enums.ArduinoPin;
import com.integreight.onesheeld.shields.ControllerParent;
import com.integreight.onesheeld.shields.observer.OnChildFocusListener;
import com.integreight.onesheeld.utils.ConnectingPinsView.onGetPinsView;
import com.integreight.onesheeld.utils.customviews.PinsColumnContainer.PinData.TYPE;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
public class PinsColumnContainer extends RelativeLayout {
public int currentIndex = -1;
public String currentTag = null;
private OnChildFocusListener focusListener;
private int extraHorizontalSpace = 0, extraVerticalSpace = 0;
private ArrayList<PinData> childrenRects = new ArrayList<PinData>();
ImageView cursor;
RelativeLayout.LayoutParams cursorParams;
ControllerParent<?> controller;
private onGetPinsView onGetPinsListener;
private boolean isOnglobalCalled = false;
public PinsColumnContainer(Context context, AttributeSet attrs) {
super(context, attrs);
extraHorizontalSpace = (int) (50 * context.getResources()
.getDisplayMetrics().density - .5f);
extraVerticalSpace = (int) (1 * context.getResources()
.getDisplayMetrics().density - .5f);
}
public void setup(OnChildFocusListener focusListener, ImageView cursor,
ControllerParent<?> controller, onGetPinsView onGetPinsListener) {
this.focusListener = focusListener;
this.cursor = cursor;
this.controller = controller;
this.onGetPinsListener = onGetPinsListener;
currentIndex = -1;
currentTag = null;
isOnglobalCalled = false;
childrenRects = new ArrayList<PinData>();
getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (!isOnglobalCalled
&& (childrenRects == null || childrenRects
.size() == 0)) {
childrenRects = new ArrayList<PinsColumnContainer.PinData>();
loadRects(PinsColumnContainer.this);
PinsColumnContainer.this.onGetPinsListener
.onPinsDrawn();
isOnglobalCalled = true;
}
}
});
}
int concatenatedLeft = 0, concatenatedTop = 0, concatenatedRight = 0;
private boolean isPinEnabled(String tag) {
for (int i = 0; i < controller.getRequiredPinsNames().length; i++) {
if (tag.equals(controller.getRequiredPinsNames()[i])) {
return true;
}
}
return false;
}
private int getType(PinView v) {
int type = PinData.TYPE.NOT_CONNECTED_AND_ENABLED;
if (v.getTag() != null) {
String tag = v.getTag().toString().startsWith("_") ? v.getTag()
.toString().substring(1) : v.getTag().toString();
if (isPinEnabled(tag) == false)
return PinData.TYPE.DISABLED;
Hashtable<String, Boolean> table = ArduinoPin.valueOf(v.getTag()
.toString()).connectedPins;
Enumeration<String> enumKey = table.keys();
while (enumKey.hasMoreElements()) {
String key = enumKey.nextElement();
if (!key.startsWith(controller.getClass().getName())) {
type = PinData.TYPE.CONNECTED_OUT;
}
}
enumKey = controller.matchedShieldPins.keys();
while (enumKey.hasMoreElements()) {
String key = enumKey.nextElement();
if (controller.matchedShieldPins.get(key) != null
&& controller.matchedShieldPins.get(key) == ArduinoPin
.valueOf(v.getTag().toString())) {
return PinData.TYPE.CONNECTED_HERE;
}
}
} else
type = TYPE.DUMMY;
return type;
}
private void loadRects(ViewGroup vg) {
concatenatedLeft = getChildAt(1).getLeft();
concatenatedTop = getChildAt(1).getTop();
concatenatedRight = getChildAt(1).getRight();
cursorParams = (LayoutParams) cursor.getLayoutParams();
for (int i = 0; i < vg.getChildCount(); i++) {
if (vg.getChildAt(i) instanceof PinView) {
PinView v = (PinView) vg.getChildAt(i);
int type = getType(v);
if (type != TYPE.DUMMY) {
v.setBackgroundResource(type);
childrenRects.add(new PinData(((String) v.getTag()),
new Rect(
concatenatedLeft
+ vg.getLeft()
- (extraHorizontalSpace * (!v
.getTag().toString()
.startsWith("_") ? 2 : 1))
+ v.getLeft(), concatenatedTop
+ vg.getTop() + v.getTop()
- extraVerticalSpace,
concatenatedTop
+ vg.getLeft()
+ v.getRight()
+ (extraHorizontalSpace * (v
.getTag().toString()
.startsWith("_") ? 2 : 2)),
concatenatedTop + vg.getTop()
+ v.getBottom()
+ extraVerticalSpace), i, type));
}
} else if (vg.getChildAt(i) instanceof ViewGroup) {
loadRects((ViewGroup) vg.getChildAt(i));
}
}
}
private synchronized PinData getTouhedIndex(MotionEvent event) {
for (PinData item : childrenRects) {
if (item.rect.contains((int) event.getX(), (int) event.getY())
&& item.type != PinData.TYPE.DISABLED)
return item;
}
return new PinData("", null, -1, PinData.TYPE.NOT_CONNECTED_AND_ENABLED);
}
public void setCursorTo(PinData item) {
cursor.setVisibility(View.VISIBLE);
cursorParams.topMargin = item.rect.top - (cursorParams.height / 2)
- (5 * extraVerticalSpace);
cursorParams.leftMargin = (item.tag.startsWith("_") ? (concatenatedLeft - extraHorizontalSpace / 2)
: (concatenatedRight + extraHorizontalSpace / 4));
cursor.setBackgroundResource(item.tag.startsWith("_") ? R.drawable.arduino_pins_view_left_selector
: R.drawable.arduino_pins_view_right_selector);
cursor.requestLayout();
}
public PinData getDataOfTag(String tag) {
for (PinData item : childrenRects) {
if (tag.equals(item.tag)) {
return item;
}
}
return new PinData("", null, -1, PinData.TYPE.NOT_CONNECTED_AND_ENABLED);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN
|| event.getAction() == MotionEvent.ACTION_MOVE) {
PinData item = getTouhedIndex(event);
if (item.index != currentIndex) {
currentIndex = item.index;
currentTag = item.tag;
if (focusListener != null)
focusListener.focusOnThisChild(currentIndex, currentIndex == -1 ? "" : currentTag);
if (item.index != -1) {
setCursorTo(item);
} else
cursor.setVisibility(View.INVISIBLE);
return true;
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
PinData item = getTouhedIndex(event);
currentIndex = item.index;
currentTag = item.tag;
if (item.index != -1) {
setCursorTo(item);
} else
if (cursor != null)
cursor.setVisibility(View.INVISIBLE);
if (focusListener != null)
focusListener.selectThisChild(currentIndex, currentIndex == -1 ? "" : currentTag);
childrenRects = new ArrayList<PinsColumnContainer.PinData>();
loadRects(this);
return true;
}
return true;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
return true;
}
public static class PinData {
public String tag;
public Rect rect;
public int index;
public int type;
public PinData() {
// TODO Auto-generated constructor stub
}
public PinData(String tag, Rect rect, int index, int type) {
super();
this.tag = tag;
this.rect = rect;
this.index = index;
this.type = type;
}
public static final class TYPE {
public final static int CONNECTED_HERE = R.drawable.arduino_green_temp_pin;
public final static int CONNECTED_OUT = R.drawable.arduino_orange_pin;
public final static int NOT_CONNECTED_AND_ENABLED = R.drawable.arduino_default_pin;
public final static int DISABLED = R.drawable.arduino_red_pin;
public final static int DUMMY = R.drawable.arduino_dummy_pin;
}
}
}