package org.openhab.habclient;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import org.openhab.domain.model.GraphicUnit;
import org.openhab.domain.model.OpenHABWidgetType;
import org.openhab.domain.model.Room;
import org.openhab.habclient.dagger.DaggerUnitContainerComponent;
import org.openhab.habclient.dagger.UnitContainerComponent;
import org.openhab.habdroid.R;
import org.openhab.habdroid.ui.IWidgetTypeLayoutProvider;
import org.openhab.habdroid.ui.WidgetTypeLayoutProvider;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.inject.Inject;
/**
* Created by Tony Alpskog in 2013.
*/
public class UnitContainerView extends FrameLayout implements RoomImageView.OnBackgroundDrawn {
private static final int UNIT_SIZE = 64;
private static final String TAG = "UnitContainerView";
OnContainerBackgroundDrawn mOnContainerBackgroundDrawn;
//TA: TODO - Will disposal of unused RoomImageView save some memory?
private RoomImageView mRoomImageView;
private Room mRoom;
private List<View> mAddedUnitViews;
private boolean mBlockUnitRedraw = false;
private View mAddedControlView = null;
private final HashMap<GraphicUnit, GraphicUnitWidget> mGraphicUnitWidgets = new HashMap<GraphicUnit, GraphicUnitWidget>();
@Inject OpenHABWidgetControl mOpenHABWidgetControl;
@Inject IRoomImageProvider mRoomImageProvider;
public UnitContainerView(Context context) {
this(context, null);
}
public UnitContainerView(Context context, AttributeSet attrs) {
super(context, attrs);
UnitContainerComponent unitContainerComponent = DaggerUnitContainerComponent.builder()
.appComponent(((HABApplication) context.getApplicationContext()).appComponent())
.build();
unitContainerComponent.inject(this);
mAddedUnitViews = new ArrayList<View>();
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT
);
setLayoutParams(params);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.room_layout, this, true);
mRoomImageView = (RoomImageView) findViewById(R.id.dropImage);
mRoomImageView.setOnBackgroundDrawnListener(this);
}
public int getScaledBitmapHeight() {
return mRoomImageView.getScaledBitmapHeight();
}
public int getScaledBitmapWidth() {
return mRoomImageView.getScaledBitmapWidth();
}
public int getScaledBitmapX() {
return mRoomImageView.getScaledBitmapX();
}
public int getScaledBitmapY() {
return mRoomImageView.getScaledBitmapY();
}
@Override
public boolean onBackgroundDrawn(View v) {
postOnContainerBackgroundDrawn();
redrawAllUnits();
return false;
}
public interface OnContainerBackgroundDrawn {
boolean onContainerBackgroundDrawn(View v);
}
public void setOnContainerBackgroundDrawnListener(OnContainerBackgroundDrawn eventListener) {
mOnContainerBackgroundDrawn = eventListener;
}
private boolean postOnContainerBackgroundDrawn() {
if(mOnContainerBackgroundDrawn != null) {
mOnContainerBackgroundDrawn.onContainerBackgroundDrawn(this);
return true;
}
return false;
}
public void redrawAllUnits() {
Log.d(TAG, "redrawAllUnits() - method called");
if(mRoom == null || mBlockUnitRedraw)
return;
removeAllUnitViews();
for(GraphicUnit graphicUnit : mRoom.getUnits()) {
mGraphicUnitWidgets.remove(graphicUnit);
drawUnitInRoom(graphicUnit);
}
}
private void drawUnitInRoom(GraphicUnit gUnit) {
int x = Math.round(getScaledBitmapX() + (getScaledBitmapWidth() / gUnit.getRoomRelativeX()));
int y = Math.round(getScaledBitmapY() + (getScaledBitmapHeight() / gUnit.getRoomRelativeY()));
drawUnitInRoom(gUnit, x, y);
if(gUnit.getOpenHABWidget().getType() == OpenHABWidgetType.ItemText)
drawControlInRoom(gUnit, x, y);
// else
// drawControlInRoom(gUnit, x-50, y-150);
}
public void drawControlInRoom(GraphicUnit gUnit) {
int x = Math.round(getScaledBitmapX() + (getScaledBitmapWidth() / gUnit.getRoomRelativeX()));
int y = Math.round(getScaledBitmapY() + (getScaledBitmapHeight() / gUnit.getRoomRelativeY()));
drawControlInRoom(gUnit, x, y);
}
public void addNewUnitToRoom(GraphicUnit gUnit, int percentOfX, int percentOfY) {
mRoom.addUnit(gUnit);
Log.d("Add unit", "addNewUnitToRoom() add unit<" + gUnit.getId() + "> to mRoom<" + mRoom.getId() + ">");
int x = ((getScaledBitmapWidth() / 100) * percentOfX) + getScaledBitmapX();
int y = ((getScaledBitmapHeight() / 100) * percentOfY) + getScaledBitmapY();
//TODO - Fix initial unit placement mismatch
gUnit.setRoomRelativeX(getScaledBitmapWidth() / (x - getScaledBitmapX()));
gUnit.setRoomRelativeY(getScaledBitmapHeight() / (y - getScaledBitmapY()));
drawUnitInRoom(gUnit, x, y);
}
private void drawUnitInRoom(GraphicUnit gUnit, int x, int y) {
//TODO - This is probably a horrible RelativeLayout work-around for a FrameLayout problem.
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout layout = (RelativeLayout)inflater.inflate(R.layout.room_layout_relative, this, false);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
params.setMargins(x, y, 0, 0);
Log.d("UnitPos", params.leftMargin + "/" + params.topMargin);
ImageView gView = getView(gUnit);
layout.addView(gView, params);
mAddedUnitViews.add(layout);
addView(layout);
}
private ImageView getView(GraphicUnit graphicUnit) {
GraphicUnitWidget view = mGraphicUnitWidgets.get(graphicUnit);
if(view == null) {
view = new GraphicUnitWidget(getContext(), graphicUnit, this);
view.setMinimumWidth(getQuickFixScaleValue(UNIT_SIZE));
view.setMinimumHeight(getQuickFixScaleValue(UNIT_SIZE));
view.setTag(graphicUnit.getId());
view.setSelected(graphicUnit.isSelected());
mGraphicUnitWidgets.put(graphicUnit, view);
}
return view;
}
private void drawControlInRoom(GraphicUnit gUnit, int x, int y) {
final IWidgetTypeLayoutProvider widgetTypeLayoutProvider = new WidgetTypeLayoutProvider();
final int layoutId = widgetTypeLayoutProvider.getControlLayoutId(gUnit.getOpenHABWidget().getType());
if(layoutId == -1)//No available layout
return;
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View inflatedView = inflater.inflate(layoutId, this, false);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
Log.d("ControlPos", params.leftMargin + "/" + params.topMargin);
View controlView = null;
if(gUnit.getOpenHABWidget().getType() == OpenHABWidgetType.Switch) {
removeControlView();
controlView = mOpenHABWidgetControl.initializeSwitchWidget(gUnit.getOpenHABWidget(), inflatedView);
params.setMargins(x - getQuickFixScaleValue(30), y + getQuickFixScaleValue(64), 0, 0);
mAddedControlView = inflatedView;
} else if(gUnit.getOpenHABWidget().getType() == OpenHABWidgetType.ItemText/* || gUnit.getOpenHABWidget().getType() == OpenHABWidgetType.SitemapText*/) {
mAddedUnitViews.add(inflatedView);
controlView = mOpenHABWidgetControl.initializeTextWidget(gUnit.getOpenHABWidget(), inflatedView);
params.setMargins(x - getQuickFixScaleValue(10), y + getQuickFixScaleValue(64), 0, 0);
}
controlView.setLayoutParams(params);
addView(inflatedView);
}
private int getQuickFixScaleValue(int baseValue)//TODO - Temporary quick and extremely dirty fix for non-scaling unit views
{
return (int)(baseValue / (1.5 / getResources().getDisplayMetrics().density));
}
public void setRoom(Room nextRoom) {
mRoom = nextRoom;
mBlockUnitRedraw = true;
setImageBitmap(mRoomImageProvider.getRoomImage(mRoom, mRoomImageView.getResources().getConfiguration().screenWidthDp, mRoomImageView.getResources().getConfiguration().screenHeightDp));
mBlockUnitRedraw = false;
redrawAllUnits();
}
public Room getRoom() {
return mRoom;
}
public void setImageBitmap(Bitmap bitmap) {
mRoomImageView.setImageBitmap(bitmap);
}
private void removeAllUnitViews() {
Log.d("Remove unit views", "Child count = " + getChildCount());
for (View addedUnitView : mAddedUnitViews) {
ViewGroup vg = (ViewGroup) addedUnitView;
vg.removeAllViewsInLayout();
removeView(vg);
}
removeControlView();
mAddedUnitViews.clear();
Log.d("Remove unit views", "Room<" + getRoom().getId() + "> Child count = " + getChildCount());
}
private void removeControlView() {
if(mAddedControlView != null) {
removeView(mAddedControlView);
}
mAddedControlView = null;
}
public void setSelected(GraphicUnit graphicUnit) {
GraphicUnitWidget graphicUnitWidget = mGraphicUnitWidgets.get(graphicUnit);
if(graphicUnitWidget != null) {
graphicUnitWidget.setSelected(graphicUnit.isSelected());
}
}
}