package mobi.monaca.framework.nativeui.component;
import static mobi.monaca.framework.nativeui.UIUtil.updateJSONObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import mobi.monaca.framework.nativeui.ComponentEventer;
import mobi.monaca.framework.nativeui.DefaultStyleJSON;
import mobi.monaca.framework.nativeui.UIContext;
import mobi.monaca.framework.nativeui.UIUtil;
import mobi.monaca.framework.nativeui.UIValidator;
import mobi.monaca.framework.nativeui.exception.NativeUIException;
import mobi.monaca.framework.nativeui.exception.RequiredKeyNotFoundException;
import mobi.monaca.framework.psedo.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
public class SegmentComponent extends ToolbarComponent {
protected SegmentComponentView view;
protected ComponentEventer eventer;
protected int backgroundColor = 0xff555555;
protected int pressedBackgroundColor;
protected static final String[] SEGMENT_VALID_KEYS = { "component", "style", "iosStyle", "androidStyle", "id", "event", };
protected static final String[] STYLE_VALID_KEYS = { "visibility", "disable", "opacity", "backgroundColor", "activeTextColor", "textColor", "texts", "activeIndex"};
@Override
public String[] getValidKeys() {
return SEGMENT_VALID_KEYS;
}
public SegmentComponent(UIContext context, JSONObject segmentJSON) throws NativeUIException, JSONException {
super(context, segmentJSON);
this.view = new SegmentComponentView(context);
UIValidator.validateKey(context, getComponentName() + " style", style, STYLE_VALID_KEYS);
buildEventer();
style();
}
private void buildEventer() throws NativeUIException, JSONException {
this.eventer = new ComponentEventer(uiContext, getComponentJSON().optJSONObject("event"));
}
public View getView() {
return view;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
}
protected void style() throws NativeUIException {
JSONArray texts = style.optJSONArray("texts");
if(texts == null){
throw new RequiredKeyNotFoundException(getComponentName() + " style", "texts");
}
backgroundColor = UIValidator.parseAndValidateColor(uiContext, getComponentName() + " style", "backgroundColor", "#ff0000", style);
int textColor = UIValidator.parseAndValidateColor(uiContext, getComponentName() + " style", "textColor", "#ffffff", style);
int activeTextColor = UIValidator.parseAndValidateColor(uiContext, getComponentName() + " style", "activeTextColor", "#ffffff", style);
if (texts != null) {
view.removeAllSegmentItemViews();
for (int i = 0; i < texts.length(); i++) {
SegmentItemView item = new SegmentItemView(uiContext, texts.optString(i), backgroundColor, textColor, activeTextColor);
if (i == 0) {
item.setAsLeft();
} else if (i == texts.length() - 1) {
item.setAsRight();
} else {
item.setAsCenter();
}
view.addSegmentItemView(item);
}
if (texts.length() == 1) {
view.setAsSingle();
}
}
view.setVisibility(style.optBoolean("visibility", true) ? View.VISIBLE : View.INVISIBLE);
view.setDisable(style.optBoolean("disable", false));
int activeIndex = UIValidator.parseAndValidateInt(uiContext, getComponentName() + " style", "activeIndex", "0", style, 0, texts.length() - 1);
view.setActiveIndex(activeIndex);
view.updateSegmentItemsWidth();
}
class SegmentComponentView extends FrameLayout implements View.OnClickListener {
protected boolean disabled = false;
protected ArrayList<SegmentItemView> items = new ArrayList<SegmentItemView>();
protected SegmentItemView currentItemView = null;
protected LinearLayout layout;
public SegmentComponentView(Context context) {
super(context);
layout = new LinearLayout(context);
layout.setOrientation(LinearLayout.HORIZONTAL);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.MATCH_PARENT);
addView(layout, layoutParams);
addView(createFrameView(), layoutParams);
}
public View createFrameView() {
View v = new FrameLayout(uiContext);
v.setBackgroundResource(R.drawable.monaca_button_frame);
v.getBackground().setAlpha(0xcc);
return v;
}
public List<SegmentItemView> getAllSegmentItems() {
return items;
}
public void setAsSingle() {
items.get(0).setAsSingle();
}
public void removeAllSegmentItemViews() {
layout.removeAllViews();
items = new ArrayList<SegmentItemView>();
}
public void setActiveIndex(int i) {
if (currentItemView != null) {
currentItemView.switchToUnselected();
}
if (i >= 0 && i < items.size()) {
currentItemView = items.get(i);
currentItemView.switchToSelected();
} else {
currentItemView = null;
}
}
public void setDisable(boolean disabled) {
this.disabled = disabled;
}
protected void addSegmentItemView(SegmentItemView itemView) {
items.add(itemView);
layout.addView(itemView, new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1));
if (items.size() == 1) {
itemView.switchToSelected();
currentItemView = itemView;
} else {
itemView.switchToUnselected();
}
itemView.setOnClickListener(this);
}
protected void updateSegmentItemsWidth() {
ArrayList<Integer> widths = new ArrayList<Integer>();
for (SegmentItemView segment : items) {
segment.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
segment.getMeasuredWidth();
widths.add(segment.getMeasuredWidth());
}
int maxWidth = Collections.max(widths);
// compensate for sdk > Honeycomb using Holo theme which make item
// width wider
if (android.os.Build.VERSION.SDK_INT >= 11) {
maxWidth = maxWidth - UIUtil.dip2px(getContext(), 15);
}
for (SegmentItemView segment : items) {
LinearLayout.LayoutParams p = (LinearLayout.LayoutParams) segment.getLayoutParams();
p.width = maxWidth;
segment.setLayoutParams(p);
}
View frame = getChildAt(1);
FrameLayout.LayoutParams p = (FrameLayout.LayoutParams) frame.getLayoutParams();
p.width = maxWidth * items.size();
frame.setLayoutParams(p);
}
@Override
public void onClick(View v) {
if (!this.disabled) {
SegmentItemView item = (SegmentItemView) v;
item.switchToSelected();
int activeIndex = 0;
for (int i = 0; i < items.size(); i++) {
if (items.get(i) == item) {
activeIndex = i;
try {
style.put("activeIndex", i);
} catch (JSONException e) {
}
break;
}
}
uiContext.react("javascript: __segment_index = " + activeIndex + ";");
if (item == currentItemView) {
eventer.onTap();
} else {
eventer.onChange();
}
if (currentItemView != null && currentItemView != item) {
currentItemView.switchToUnselected();
}
currentItemView = item;
}
}
}
@Override
public void updateStyle(JSONObject update) throws NativeUIException {
updateJSONObject(style, update);
style();
}
public class SegmentItemView extends FrameLayout {
protected Button button;
protected boolean isSelected = true;
protected int tint;
protected int textColor, activeTextColor;
protected SegmentBackgroundDrawable background;
public SegmentItemView(UIContext context, String title, int tint, int textColor, int activeTextColor) {
super(context);
this.tint = tint;
this.textColor = textColor;
this.activeTextColor = activeTextColor;
button = new Button(context);
button.setText(title);
button.setGravity(Gravity.CENTER | Gravity.CENTER_VERTICAL);
button.setTextColor(this.textColor);
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getFontSizeFromDip(Component.SEGMENT_TEXT_DIP));
button.setShadowLayer(1f, 0f, -1f, 0xcc000000);
addView(button, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
setAsSingle();
switchToUnselected();
}
public void setAsLeft() {
background = new SegmentBackgroundDrawable(uiContext, SegmentBackgroundDrawable.Type.LEFT, tint);
button.setBackgroundDrawable(background);
}
public void setAsRight() {
background = new SegmentBackgroundDrawable(uiContext, SegmentBackgroundDrawable.Type.RIGHT, tint);
button.setBackgroundDrawable(background);
}
public void setAsCenter() {
background = new SegmentBackgroundDrawable(uiContext, SegmentBackgroundDrawable.Type.CENTER, tint);
button.setBackgroundDrawable(background);
}
public void setAsSingle() {
background = new SegmentBackgroundDrawable(uiContext, SegmentBackgroundDrawable.Type.SINGLE, tint);
button.setBackgroundDrawable(background);
}
@Override
public void setOnClickListener(final View.OnClickListener listener) {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onClick(SegmentItemView.this);
}
});
}
public void switchToSelected() {
background.setSelected(true);
isSelected = true;
button.setTextColor(this.activeTextColor);
invalidate();
}
public void switchToUnselected() {
background.setSelected(false);
isSelected = false;
button.setTextColor(this.textColor);
invalidate();
}
protected void updateSwitchingEffect() {
if (isSelected) {
switchToSelected();
} else {
switchToUnselected();
}
}
public boolean isSelected() {
return isSelected;
}
}
@Override
public String getComponentName() {
return "Segment";
}
@Override
public JSONObject getDefaultStyle() {
return DefaultStyleJSON.segment();
}
}