package com.tsi.navi.activity.fragment; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.Context; import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import com.tsi.navi.R; import com.tsi.navi.TsiNaviApplication; import com.tsi.navi.activity.model.CpuControl; import com.tsi.navi.activity.model.SignalItem; import com.tsi.navi.dto.CpuNodeStatusDTO; import com.tsi.navi.util.TsiUtils; import com.tsi.navi.vo.NodeVo; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; public class DirectionNaviSignalFragment extends Fragment { private static final String TAG = DirectionNaviSignalFragment.class.getSimpleName(); private Context context; private NodeVo node; private long nodeId; private CpuControl cpuControl; private TextView tvCycle; private ImageView[] imgSignal = new ImageView[4]; private int directionCode; private boolean first; private Set directions = new HashSet(); private final int MAX_SIGNAL = 4; private int[] sigIdx = new int[MAX_SIGNAL]; private int[][] signalId = { { // RED R.drawable.ic_sig_off, R.drawable.ic_sig_red, }, { // YELLOW R.drawable.ic_sig_off, R.drawable.ic_sig_yellow, }, { // LEFT R.drawable.ic_sig_left_off, R.drawable.ic_sig_left_on, }, { // STRAIGHT R.drawable.ic_sig_off, R.drawable.ic_sig_green, }, }; private int[][] signalIdUn = { { // none R.drawable.rect_none, // 데이터 없음. R.drawable.rect_none, // 데이터 없음. R.drawable.rect_none, // 데이터 없음. R.drawable.rect_none, // 데이터 없음. R.drawable.rect_none, // 데이터 없음. R.drawable.rect_none, // 데이터 없음. R.drawable.rect_none, // 데이터 없음. R.drawable.rect_none, // 데이터 없음. }, { // 직진 R.drawable.ic_signal_straight_off_un, // LIGHTS_OUT (0, "LIGHTS_OUT"), //소등 R.drawable.ic_signal_straight_red_un, // RED_SOLID (1, "RED_SOLID"), //적색점등 R.drawable.ic_signal_straight_yellow_un, // YELLOW_SOLID (2, "YELLOW_SOLID"), //황색점등 R.drawable.ic_signal_straight_green_un, // GREEN_SOLID (3, "GREEN_SOLID"), //녹색점등 R.drawable.ic_signal_straight_red_un, // RED_BLINK (4, "RED_BLINK"), //적색점멸 R.drawable.ic_signal_straight_yellow_un, // YELLOW_BLINK (5, "YELLOW_BLINK"), //황색점멸 R.drawable.ic_signal_straight_green_un, // GREEN_BLINK (6, "GREEN_BLINK"); //녹색점멸 R.drawable.rect_none, // 데이터 없음. }, { // 좌회전 R.drawable.ic_signal_left_off_un, // LIGHTS_OUT (0, "LIGHTS_OUT"), //소등 R.drawable.ic_signal_left_red_un, // RED_SOLID (1, "RED_SOLID"), //적색점등 R.drawable.ic_signal_left_yellow_un, // YELLOW_SOLID (2, "YELLOW_SOLID"), //황색점등 R.drawable.ic_signal_left_green_un, // GREEN_SOLID (3, "GREEN_SOLID"), //녹색점등 R.drawable.ic_signal_left_red_un, // RED_BLINK (4, "RED_BLINK"), //적색점멸 R.drawable.ic_signal_left_yellow_un, // YELLOW_BLINK (5, "YELLOW_BLINK"), //황색점멸 R.drawable.ic_signal_left_green_un, // GREEN_BLINK (6, "GREEN_BLINK"); //녹색점멸 R.drawable.rect_none, // 데이터 없음. }, { // 보행자 R.drawable.ic_signal_walk_off_un, // LIGHTS_OUT (0, "LIGHTS_OUT"), //소등 R.drawable.ic_signal_walk_red_un, // RED_SOLID (1, "RED_SOLID"), //적색점등 R.drawable.ic_signal_walk_yellow_un, // YELLOW_SOLID (2, "YELLOW_SOLID"), //황색점등 R.drawable.ic_signal_walk_green_un, // GREEN_SOLID (3, "GREEN_SOLID"), //녹색점등 R.drawable.ic_signal_walk_red_un, // RED_BLINK (4, "RED_BLINK"), //적색점멸 R.drawable.ic_signal_walk_yellow_un, // YELLOW_BLINK (5, "YELLOW_BLINK"), //황색점멸 R.drawable.ic_signal_walk_green_un, // GREEN_BLINK (6, "GREEN_BLINK"); //녹색점멸 R.drawable.rect_none, // 데이터 없음. }, { // 자전거 R.drawable.ic_signal_off_un, // LIGHTS_OUT (0, "LIGHTS_OUT"), //소등 R.drawable.ic_signal_red_un, // RED_SOLID (1, "RED_SOLID"), //적색점등 R.drawable.ic_signal_yellow_un, // YELLOW_SOLID (2, "YELLOW_SOLID"), //황색점등 R.drawable.ic_signal_green_un, // GREEN_SOLID (3, "GREEN_SOLID"), //녹색점등 R.drawable.ic_signal_red_un, // RED_BLINK (4, "RED_BLINK"), //적색점멸 R.drawable.ic_signal_yellow_un, // YELLOW_BLINK (5, "YELLOW_BLINK"), //황색점멸 R.drawable.ic_signal_green_un, // GREEN_BLINK (6, "GREEN_BLINK"); //녹색점멸 R.drawable.rect_none, // 데이터 없음. }, { // 우회전 R.drawable.ic_signal_off_un, // LIGHTS_OUT (0, "LIGHTS_OUT"), //소등 R.drawable.ic_signal_red_un, // RED_SOLID (1, "RED_SOLID"), //적색점등 R.drawable.ic_signal_yellow_un, // YELLOW_SOLID (2, "YELLOW_SOLID"), //황색점등 R.drawable.ic_signal_green_un, // GREEN_SOLID (3, "GREEN_SOLID"), //녹색점등 R.drawable.ic_signal_red_un, // RED_BLINK (4, "RED_BLINK"), //적색점멸 R.drawable.ic_signal_yellow_un, // YELLOW_BLINK (5, "YELLOW_BLINK"), //황색점멸 R.drawable.ic_signal_green_un, // GREEN_BLINK (6, "GREEN_BLINK"); //녹색점멸 R.drawable.rect_none, // 데이터 없음. }, { // 버스 R.drawable.ic_signal_off_un, // LIGHTS_OUT (0, "LIGHTS_OUT"), //소등 R.drawable.ic_signal_red_un, // RED_SOLID (1, "RED_SOLID"), //적색점등 R.drawable.ic_signal_yellow_un, // YELLOW_SOLID (2, "YELLOW_SOLID"), //황색점등 R.drawable.ic_signal_green_un, // GREEN_SOLID (3, "GREEN_SOLID"), //녹색점등 R.drawable.ic_signal_red_un, // RED_BLINK (4, "RED_BLINK"), //적색점멸 R.drawable.ic_signal_yellow_un, // YELLOW_BLINK (5, "YELLOW_BLINK"), //황색점멸 R.drawable.ic_signal_green_un, // GREEN_BLINK (6, "GREEN_BLINK"); //녹색점멸 R.drawable.rect_none, // 데이터 없음. }, { // 유턴 R.drawable.ic_signal_uturn_off_un, // LIGHTS_OUT (0, "LIGHTS_OUT"), //소등 R.drawable.ic_signal_uturn_red_un, // RED_SOLID (1, "RED_SOLID"), //적색점등 R.drawable.ic_signal_uturn_yellow_un, // YELLOW_SOLID (2, "YELLOW_SOLID"), //황색점등 R.drawable.ic_signal_uturn_green_un, // GREEN_SOLID (3, "GREEN_SOLID"), //녹색점등 R.drawable.ic_signal_uturn_red_un, // RED_BLINK (4, "RED_BLINK"), //적색점멸 R.drawable.ic_signal_uturn_yellow_un, // YELLOW_BLINK (5, "YELLOW_BLINK"), //황색점멸 R.drawable.ic_signal_uturn_green_un, // GREEN_BLINK (6, "GREEN_BLINK"); //녹색점멸 R.drawable.rect_none, // 데이터 없음. }, }; private SignalItem signalCurr = null; private SignalItem signalPrev = null; // 소등(0), 적색점등(1), 황색점등(2), 녹색점등(3), 적색점멸(4), 황색점멸(5), 녹색점멸(6) // 미지정(0), 직진(1), 좌회전(2), 보행자(3), 자전거(4), 우회전(5), 버스(6), 유턴(7) @Override public void onAttach(Context context) { super.onAttach(context); this.context = context; } @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_direction_navi_signal, container, false); this.tvCycle = v.findViewById(R.id.tv_cycle); this.tvCycle.setOnClickListener(view -> { if (this.directions.size() == 0) { return; } Log.e("Direction", this.directions.toString()); List directionList = new ArrayList(this.directions); Collections.sort(directionList); String[] dirs = new String[directionList.size()]; for(int ii = 0; ii < directionList.size(); ii++) { dirs[ii] = TsiNaviApplication.getDirection().getName(Integer.parseInt(directionList.get(ii))); } Log.e("Direction", dirs.toString()); AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle("방향코드 선택"); builder.setItems(dirs, (dialog, which) -> { int selDirection = TsiNaviApplication.getDirection().getNameCode(dirs[which]); if (selDirection != directionCode) { initStatus(); setDirectionCode(selDirection); } } ); builder.show(); }); this.imgSignal[0] = (ImageView) v.findViewById(R.id.img_red); this.imgSignal[1] = (ImageView) v.findViewById(R.id.img_yellow); this.imgSignal[2] = (ImageView) v.findViewById(R.id.img_left); this.imgSignal[3] = (ImageView) v.findViewById(R.id.img_straight); this.first = false; this.directionCode = 0; if (this.signalCurr == null) { this.signalCurr = new SignalItem(); } if (this.signalPrev == null) { this.signalPrev = new SignalItem(); } this.cpuControl = new CpuControl(); this.nodeId = 0; init(0); return v; } protected void setDirectionCode(int directionCode) { this.directionCode = directionCode; String name = TsiNaviApplication.getDirection().getName(this.directionCode); this.signalCurr.setDirection(this.directionCode); this.signalPrev.setDirection(this.directionCode); } protected void init(int directionCode) { if (this.node != null) { this.nodeId = this.node.getNodeId(); } else { this.nodeId = 0; } initStatus(); setDirectionCode(directionCode); } @SuppressLint("ObsoleteSdkInt") public void initStatus() { this.cpuControl.init(); for (int ii = 0; ii < this.MAX_SIGNAL; ii++) { if (this.imgSignal[ii] != null) { if (this.imgSignal[ii].getAnimation() != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { this.imgSignal[ii].getAnimation().cancel(); } this.imgSignal[ii].clearAnimation(); this.imgSignal[ii].setAnimation(null); } this.imgSignal[ii].setImageResource(signalId[ii][0]); } } this.signalCurr.initStatus(); this.signalPrev.initStatus(); } public long getNodeId() { return this.nodeId; } public void setNodeCross(NodeVo node, int directionCode) { this.first = true; this.node = node; init(directionCode); } @SuppressLint("ObsoleteSdkInt") public void updateSignal(CpuNodeStatusDTO status) { if (this.node == null || this.nodeId != status.getA()) { return; } if (this.first) { this.directions.clear(); int directionCode = this.directionCode; for (int ii = 0; ii < status.getG().size(); ii++) { this.directions.add(String.valueOf(status.getG().get(ii).getH())); if (ii == 0) { directionCode = status.getG().get(ii).getH(); } if (this.directionCode == status.getG().get(ii).getH()) { directionCode = this.directionCode; } } // 프로그램에서 설정한 방향코드가 수집한 상태정보의 방향코드에 존재하지 않으면 첫번째 방향코드로 변경한다. if (this.directionCode != directionCode) { setDirectionCode(directionCode); } this.first = false; } this.cpuControl.updateStatus(status.getD()); // 방향코드에 맞는 데이터 표출 for (int ii = 0; ii < status.getG().size(); ii++) { if (status.getG().get(ii).getH() == this.directionCode) { this.signalCurr.setStatus(status.getG().get(ii)); } } int lightStatus; int remainSeconds; for (int ii = 0; ii < this.MAX_SIGNAL; ii++) { this.sigIdx[ii] = 0; } boolean isBlink = false; remainSeconds = this.signalCurr.getRemainTime(TsiUtils.SIGNAL_STRAIGHT); lightStatus = this.signalCurr.getLightStatus(TsiUtils.SIGNAL_STRAIGHT); switch (lightStatus) { case 0: // light out break; case 1: // red solid this.sigIdx[0] = 1; break; case 4: // red blink this.sigIdx[0] = 1; isBlink = true; break; case 2: // yellow solid this.sigIdx[1] = 1; break; case 5: // yellow blink this.sigIdx[1] = 1; isBlink = true; break; case 3: // green solid this.sigIdx[3] = 1; break; case 6: // green blink this.sigIdx[3] = 1; isBlink = true; break; } lightStatus = this.signalCurr.getLightStatus(TsiUtils.SIGNAL_LEFT_TURN); switch (lightStatus) { case 0: // light out break; case 1: // red solid this.sigIdx[0] = 1; break; case 4: // red blink this.sigIdx[0] = 1; isBlink = true; break; case 2: // yellow solid this.sigIdx[1] = 1; break; case 5: // yellow blink this.sigIdx[1] = 1; isBlink = true; break; case 3: // green solid this.sigIdx[2] = 1; break; case 6: // green blink this.sigIdx[2] = 1; isBlink = true; break; } if (lightStatus == 2 || lightStatus == 5) { // YELLOW 일때 if (this.sigIdx[0] == 1) { remainSeconds = this.signalCurr.getRemainTime(TsiUtils.SIGNAL_LEFT_TURN); } } if (this.sigIdx[2] == 1 && this.sigIdx[0] == 1) { // 좌회전, 레드가 모구 켜져있으면 좌회전 신호 표출 this.sigIdx[0] = 0; remainSeconds = this.signalCurr.getRemainTime(TsiUtils.SIGNAL_LEFT_TURN); } if (this.sigIdx[1] == 1 && this.sigIdx[0] == 1) { // 레드, 옐로우 켜져 있으면 옐로우 신호 표출 this.sigIdx[0] = 0; } if (remainSeconds < 0) remainSeconds = 255; this.tvCycle.setText(" " +String.valueOf(remainSeconds)); for (int ii = 0; ii < this.MAX_SIGNAL; ii++) { if (this.imgSignal[ii].getAnimation() != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { this.imgSignal[ii].getAnimation().cancel(); } this.imgSignal[ii].clearAnimation(); this.imgSignal[ii].setAnimation(null); } this.imgSignal[ii].setImageResource(signalId[ii][this.sigIdx[ii]]); if (isBlink && this.sigIdx[ii] == 1) { Animation animation = AnimationUtils.loadAnimation(this.context, R.anim.blink); this.imgSignal[ii].startAnimation(animation); } } } }