Project

General

Profile

Download (9.34 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / states / RubikStateSolving.java @ 807d82b7

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.states;
21

    
22
import android.content.SharedPreferences;
23
import android.util.DisplayMetrics;
24
import android.view.LayoutInflater;
25
import android.view.View;
26
import android.widget.Button;
27
import android.widget.ImageButton;
28
import android.widget.LinearLayout;
29
import android.widget.TextView;
30

    
31
import org.distorted.main.R;
32
import org.distorted.main.RubikActivity;
33
import org.distorted.main.RubikPostRender;
34
import org.distorted.objects.RubikObject;
35
import org.distorted.objects.RubikObjectList;
36
import org.distorted.scores.RubikScores;
37

    
38
import java.util.ArrayList;
39
import java.util.Timer;
40
import java.util.TimerTask;
41

    
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

    
44
public class RubikStateSolving extends RubikStateAbstract implements RubikPostRender.ActionFinishedListener
45
  {
46
  private static final int DURATION_MILLIS = 750;
47

    
48
  private TextView mTime;
49
  private Timer mTimer;
50
  private long mStartTime;
51
  private boolean mRunning;
52
  private RubikScores mScores;
53
  private ImageButton mPrevButton;
54
  private boolean mCanPrevMove;
55
  private ArrayList<Move> mMoves;
56

    
57
  private static class Move
58
    {
59
    private int mAxis, mRow, mAngle;
60

    
61
    Move(int axis, int row, int angle)
62
      {
63
      mAxis = axis;
64
      mRow  = row;
65
      mAngle= angle;
66
      }
67
    }
68

    
69
///////////////////////////////////////////////////////////////////////////////////////////////////
70

    
71
  RubikStateSolving()
72
    {
73
    mScores = RubikScores.getInstance();
74
    }
75

    
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77

    
78
  void leaveState(RubikActivity act)
79
    {
80
    stopCounting();
81
    }
82

    
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

    
85
  void enterState(final RubikActivity act)
86
    {
87
    mCanPrevMove = true;
88

    
89
    if( mMoves==null ) mMoves = new ArrayList<>();
90
    else               mMoves.clear();
91

    
92
    LayoutInflater inflater = act.getLayoutInflater();
93
    DisplayMetrics metrics = act.getResources().getDisplayMetrics();
94
    float scale = metrics.density;
95

    
96
    // TOP ////////////////////////////
97
    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
98
    layoutTop.removeAllViews();
99
    mTime = (TextView)inflater.inflate(R.layout.upper_text, null);
100
    mTime.setText(act.getString(R.string.tm_placeholder,0,0));
101
    layoutTop.addView(mTime);
102

    
103
    // BOT ////////////////////////////
104
    LinearLayout layoutLeft = act.findViewById(R.id.mainBarLeft);
105
    layoutLeft.removeAllViews();
106

    
107
    if( mPrevButton==null ) setupPrevMoveButtom(act,scale);
108
    layoutLeft.addView(mPrevButton);
109

    
110
    LinearLayout layoutRight = act.findViewById(R.id.mainBarRight);
111
    layoutRight.removeAllViews();
112

    
113
    int padding = (int)(5*scale + 0.5f);
114
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
115

    
116
    Button back = new Button(act);
117
    back.setLayoutParams(params);
118
    back.setPadding(padding,0,padding,0);
119
    back.setText(R.string.back);
120

    
121
    back.setOnClickListener( new View.OnClickListener()
122
      {
123
      @Override
124
      public void onClick(View v)
125
        {
126
        RubikState.goBack(act);
127
        }
128
      });
129

    
130
    layoutRight.addView(back);
131
    }
132

    
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

    
135
  private void setupPrevMoveButtom(final RubikActivity act, float scale)
136
    {
137
    int padding = (int)( 3*scale + 0.5f);
138
    int width   = (int)(60*scale + 0.5f);
139
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width,LinearLayout.LayoutParams.MATCH_PARENT);
140
    mPrevButton = new ImageButton(act);
141
    mPrevButton.setLayoutParams(params);
142
    mPrevButton.setPadding(padding,0,padding,0);
143
    mPrevButton.setImageResource(R.drawable.left);
144
    mPrevButton.setVisibility(View.INVISIBLE);
145

    
146
    mPrevButton.setOnClickListener( new View.OnClickListener()
147
      {
148
      @Override
149
      public void onClick(View v)
150
        {
151
        RubikPostRender post = act.getPostRender();
152
        backMove(post);
153
        }
154
      });
155
    }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  private void backMove(RubikPostRender post)
160
    {
161
    if( mCanPrevMove )
162
      {
163
      int numMoves = mMoves.size();
164

    
165
      if( numMoves>0 )
166
        {
167
        Move move = mMoves.remove(numMoves-1);
168
        RubikObject object = post.getObject();
169

    
170
        int axis  = move.mAxis;
171
        int row   = (1<<move.mRow);
172
        int angle = move.mAngle;
173
        int numRot= Math.abs(angle*object.getBasicAngle()/360);
174

    
175
        if( angle!=0 )
176
          {
177
          mCanPrevMove = false;
178
          post.addRotation(this, axis, row, -angle, numRot*DURATION_MILLIS);
179

    
180
          if( numMoves==1 )
181
            {
182
            mPrevButton.setVisibility(View.INVISIBLE);
183
            }
184
          }
185
        else
186
          {
187
          android.util.Log.e("solution", "error: trying to back move of angle 0");
188
          }
189
        }
190
      else
191
        {
192
        android.util.Log.e("solv", "error: no moves to back!");
193
        }
194
      }
195
    }
196

    
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198

    
199
  public void addMove(int axis, int row, int angle)
200
    {
201
    mMoves.add(new Move(axis,row,angle));
202

    
203
    if( mMoves.size()==1 )
204
      {
205
      mPrevButton.setVisibility(View.VISIBLE);
206
      }
207
    }
208

    
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210

    
211
  public void savePreferences(SharedPreferences.Editor editor)
212
    {
213
    mPrevButton = null;
214

    
215
    editor.putLong("stateSolving_startTime" , mStartTime);
216
    mScores.savePreferences(editor);
217
    }
218

    
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

    
221
  public void restorePreferences(SharedPreferences preferences)
222
    {
223
    mStartTime = preferences.getLong("stateSolving_startTime" , 0 );
224
    mScores.restorePreferences(preferences);
225
    }
226

    
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228

    
229
  public void startCounting(final RubikActivity act)
230
    {
231
    if( !mRunning )
232
      {
233
      mRunning = true;
234
      mStartTime = System.currentTimeMillis();
235
      mTimer = new Timer();
236

    
237
      mTimer.scheduleAtFixedRate(new TimerTask()
238
        {
239
        @Override
240
        public void run()
241
          {
242
          act.runOnUiThread(new Runnable()
243
            {
244
            @Override
245
            public void run()
246
              {
247
              int elapsed = (int)(System.currentTimeMillis()-mStartTime)/1000;
248
              mTime.setText(act.getString(R.string.tm_placeholder,elapsed/60,elapsed%60));
249
              }
250
            });
251
          }
252
        }, 0, 1000);
253
      }
254
    }
255

    
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257

    
258
  public long stopCounting()
259
    {
260
    if( mRunning )
261
      {
262
      if( mTimer!=null )
263
        {
264
        mTimer.cancel();
265
        mTimer = null;
266
        }
267
      mRunning = false;
268

    
269
      long timeTaken = System.currentTimeMillis()-mStartTime;
270

    
271
      RubikStatePlay play = (RubikStatePlay)RubikState.PLAY.getStateClass();
272
      int object  = play.getObject();
273
      int size    = play.getSize();
274
      int level   = play.getLevel();
275
      int realSize= RubikObjectList.getSizeIndex(object,size);
276

    
277
      boolean isNew = mScores.setRecord(object, realSize, level, timeTaken);
278

    
279
      return isNew ? timeTaken : -timeTaken;
280
      }
281

    
282
    return 0;
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  public void onActionFinished(final long effectID)
288
    {
289
    mCanPrevMove = true;
290
    }
291
  }
(10-10/10)