Project

General

Profile

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

magiccube / src / main / java / org / distorted / screens / RubikScreenPlay.java @ b600ccd9

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.screens;
21

    
22
import android.content.Context;
23
import android.content.SharedPreferences;
24
import android.content.res.Resources;
25
import android.graphics.drawable.BitmapDrawable;
26
import android.os.Build;
27
import android.os.Bundle;
28
import android.util.TypedValue;
29
import android.view.Gravity;
30
import android.view.LayoutInflater;
31
import android.view.View;
32
import android.widget.Button;
33
import android.widget.GridLayout;
34
import android.widget.ImageButton;
35
import android.widget.LinearLayout;
36
import android.widget.PopupWindow;
37

    
38
import org.distorted.objectlib.main.ObjectControl;
39
import org.distorted.objectlib.main.ObjectType;
40

    
41
import org.distorted.main.R;
42
import org.distorted.main.RubikActivity;
43
import org.distorted.dialogs.RubikDialogAbout;
44
import org.distorted.dialogs.RubikDialogPattern;
45
import org.distorted.dialogs.RubikDialogScores;
46
import org.distorted.dialogs.RubikDialogTutorial;
47
import org.distorted.helpers.TransparentButton;
48
import org.distorted.helpers.TransparentImageButton;
49
import org.distorted.network.RubikScores;
50

    
51
import static android.view.View.inflate;
52
import static org.distorted.objectlib.main.ObjectType.NUM_OBJECTS;
53

    
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

    
56
public class RubikScreenPlay extends RubikScreenBase
57
  {
58
  public static final int NUM_COLUMNS  = 4;
59
  public static final int LEVELS_SHOWN = 10;
60
  public static int MAX_LEVEL;
61
  public static final ObjectType DEF_OBJECT= ObjectType.CUBE_3;
62

    
63
  private static final int[] BUTTON_LABELS = { R.string.scores,
64
                                               R.string.patterns,
65
                                               R.string.solver,
66
                                               R.string.tutorials,
67
                                               R.string.about };
68

    
69
  private static final int NUM_BUTTONS = BUTTON_LABELS.length;
70
  private static final float LAST_BUTTON = 1.5f;
71
  private static final int[] mLocation = new int[2];
72

    
73
  private TransparentImageButton mObjButton, mMenuButton, mSolveButton, mScrambleButton, mDetailsButton;
74
  private TransparentButton mPlayButton;
75
  private PopupWindow mObjectPopup, mMenuPopup, mPlayPopup;
76
  private ObjectType mObject = DEF_OBJECT;
77
  private int mObjectSize, mMenuLayoutWidth, mMenuLayoutHeight, mPlayLayoutWidth;
78
  private int mLevelValue;
79
  private float mButtonSize, mMenuItemSize, mMenuTextSize;
80
  private int mColCount, mRowCount, mMaxRowCount;
81
  private LinearLayout mPlayLayout;
82
  private int mUpperBarHeight;
83
  private boolean mShouldReactToEndOfScrambling;
84

    
85
  static
86
    {
87
    ObjectType[] types = ObjectType.values();
88
    int max = Integer.MIN_VALUE;
89

    
90
    for (ObjectType type : types)
91
      {
92
      int cur = getDBLevel(type);
93
      if( cur>max ) max = cur;
94
      }
95

    
96
    MAX_LEVEL = max;
97
    }
98

    
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

    
101
  void leaveScreen(RubikActivity act)
102
    {
103

    
104
    }
105

    
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107

    
108
  void enterScreen(final RubikActivity act)
109
    {
110
    float width = act.getScreenWidthInPixels();
111
    mUpperBarHeight = act.getHeightUpperBar();
112

    
113
    mMenuTextSize = width*RubikActivity.MENU_MED_TEXT_SIZE;
114
    mButtonSize   = width*RubikActivity.BUTTON_TEXT_SIZE;
115
    mMenuItemSize = width*RubikActivity.MENU_ITEM_SIZE;
116

    
117
    mRowCount = (NUM_OBJECTS + NUM_COLUMNS-1) / NUM_COLUMNS;
118
    mColCount = NUM_COLUMNS;
119

    
120
    // TOP ////////////////////////////
121
    LinearLayout layoutTop = act.findViewById(R.id.upperBar);
122
    layoutTop.removeAllViews();
123

    
124
    setupObjectButton(act,width);
125
    layoutTop.addView(mObjButton);
126

    
127
    setupMenuButton(act,width);
128
    layoutTop.addView(mMenuButton);
129

    
130
    setupPlayButton(act,width);
131
    layoutTop.addView(mPlayButton);
132

    
133
    setupSolveButton(act);
134
    setupScrambleButton(act);
135
    createBottomPane(act,mSolveButton,mScrambleButton);
136
    }
137

    
138
//////////////////////////////////////////////////////////////////////////////////////////////////
139

    
140
  private void setupObjectButton(final RubikActivity act, final float width)
141
    {
142
    final int margin  = (int)(width*RubikActivity.MARGIN);
143
    final int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_menu,R.drawable.ui_medium_cube_menu, R.drawable.ui_big_cube_menu, R.drawable.ui_huge_cube_menu);
144
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
145
    mObjButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
146

    
147
    mObjButton.setOnClickListener( new View.OnClickListener()
148
      {
149
      @Override
150
      public void onClick(View view)
151
        {
152
        if( mObjectPopup==null )
153
          {
154
          float width = act.getScreenWidthInPixels();
155
          float height= act.getScreenHeightInPixels();
156
          setupObjectWindow(act,width,height);
157
          }
158

    
159
        if( act.getControl().isUINotBlocked())
160
          {
161
          int rowCount = Math.min(mMaxRowCount,mRowCount);
162
          View popupView = mObjectPopup.getContentView();
163
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
164
          displayPopup(act,view,mObjectPopup,mObjectSize*mColCount,mObjectSize*rowCount,margin,margin);
165
          }
166
        }
167
      });
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

    
172
  private void setupPlayButton(final RubikActivity act, final float width)
173
    {
174
    final int margin = (int)(width*RubikActivity.MARGIN);
175

    
176
    mPlayButton = new TransparentButton(act, R.string.play, mButtonSize);
177

    
178
    mPlayButton.setOnClickListener( new View.OnClickListener()
179
      {
180
      @Override
181
      public void onClick(View view)
182
        {
183
         if( mPlayPopup==null )
184
          {
185
          float width = act.getScreenWidthInPixels();
186
          setupPlayWindow(act,width);
187
          }
188

    
189
        if( act.getControl().isUINotBlocked())
190
          {
191
          float height= act.getScreenHeightInPixels();
192
          final int maxHeight= (int)(0.9f*(height-mUpperBarHeight) );
193
          View popupView = mPlayPopup.getContentView();
194
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
195
          final int dbLevel = getDBLevel(mObject);
196
          final int levelsShown = Math.min(dbLevel,LEVELS_SHOWN);
197
          final int popupHeight = (int)(levelsShown*(mMenuItemSize+margin)+3*margin+mMenuItemSize*(LAST_BUTTON-1.0f));
198
          final int realHeight = Math.min(popupHeight,maxHeight);
199
          displayPopup(act,view,mPlayPopup,mPlayLayoutWidth,realHeight,margin,margin);
200
          }
201
        }
202
      });
203
    }
204

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

    
207
  private void setupMenuButton(final RubikActivity act, final float width)
208
    {
209
    final int margin = (int)(width*RubikActivity.MARGIN);
210
    final int icon = RubikActivity.getDrawable(R.drawable.ui_small_menu,R.drawable.ui_medium_menu, R.drawable.ui_big_menu, R.drawable.ui_huge_menu);
211
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
212
    mMenuButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
213

    
214
    mMenuButton.setOnClickListener( new View.OnClickListener()
215
      {
216
      @Override
217
      public void onClick(View view)
218
        {
219
        if( mMenuPopup==null )
220
          {
221
          float width = act.getScreenWidthInPixels();
222
          setupMenuWindow(act,width);
223
          }
224

    
225
        if( act.getControl().isUINotBlocked())
226
          {
227
          View popupView = mMenuPopup.getContentView();
228
          popupView.setSystemUiVisibility(RubikActivity.FLAGS);
229
          displayPopup(act,view,mMenuPopup,mMenuLayoutWidth,mMenuLayoutHeight,(int)(-width/12),margin);
230
          }
231
        }
232
      });
233
    }
234

    
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236

    
237
  private void setupObjectWindow(final RubikActivity act, final float width, final float height)
238
    {
239
    int icon = RubikActivity.getDrawable(R.drawable.cube_2s,R.drawable.cube_2m, R.drawable.cube_2b, R.drawable.cube_2h);
240

    
241
    Resources res = act.getResources();
242
    BitmapDrawable bd = (BitmapDrawable)res.getDrawable(icon);
243
    int cubeWidth = bd.getIntrinsicWidth();
244
    int margin = (int)(width*RubikActivity.LARGE_MARGIN);
245
    mObjectSize = (int)(cubeWidth + 2*margin + 0.5f);
246
    mMaxRowCount = (int)((height-2.0f*mUpperBarHeight)/mObjectSize);
247

    
248
    int viewID = mMaxRowCount<mRowCount ? R.layout.popup_object_withscroll : R.layout.popup_object_scrollless;
249
    View view = inflate( act, viewID, null);
250
    GridLayout objectGrid = view.findViewById(R.id.objectGrid);
251

    
252
    GridLayout.Spec[] rowSpecs = new GridLayout.Spec[mRowCount];
253
    GridLayout.Spec[] colSpecs = new GridLayout.Spec[mColCount];
254

    
255
    objectGrid.setColumnCount(mColCount);
256
    objectGrid.setRowCount(mRowCount);
257

    
258
    LinearLayout bottomLayout = view.findViewById(R.id.bottomLayout);
259
    setupDetailsButton(act);
260
    bottomLayout.addView(mDetailsButton);
261

    
262
    mObjectPopup = new PopupWindow(act);
263
    mObjectPopup.setFocusable(true);
264
    mObjectPopup.setContentView(view);
265

    
266
    int[] nextInRow = new int[mRowCount];
267

    
268
    for(int row=0; row<mRowCount; row++)
269
      {
270
      rowSpecs[row] = GridLayout.spec(row);
271
      nextInRow[row]= 0;
272
      }
273
    for(int col=0; col<mColCount; col++)
274
      {
275
      colSpecs[col] = GridLayout.spec(col);
276
      }
277

    
278
    for(int object = 0; object< NUM_OBJECTS; object++)
279
      {
280
      final ObjectType type = ObjectType.getObject(object);
281
      int iconSize = RubikActivity.getDrawableSize();
282
      int icons = type.getIconID(iconSize);
283
      int row = object/NUM_COLUMNS;
284

    
285
      ImageButton button = new ImageButton(act);
286
      button.setBackgroundResource(icons);
287
      button.setOnClickListener( new View.OnClickListener()
288
        {
289
        @Override
290
        public void onClick(View v)
291
          {
292
          if( act.getControl().isUINotBlocked() && ScreenList.getCurrentScreen()== ScreenList.PLAY )
293
            {
294
            mObject = type;
295
            act.changeObject(type, true);
296
            if( mPlayLayout!=null ) adjustLevels(act);
297
            mMovesController.clearMoves(act);
298
            }
299

    
300
          mObjectPopup.dismiss();
301
          }
302
        });
303

    
304
      GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpecs[row],colSpecs[nextInRow[row]]);
305
      params.bottomMargin = margin;
306
      params.topMargin    = margin;
307
      params.leftMargin   = margin;
308
      params.rightMargin  = margin;
309

    
310
      nextInRow[row]++;
311

    
312
      objectGrid.addView(button, params);
313
      }
314
    }
315

    
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317

    
318
  private void setupMenuWindow(final RubikActivity act, final float width)
319
    {
320
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
321
    final View layout = layoutInflater.inflate(R.layout.popup_menu, null);
322
    LinearLayout menuLayout = layout.findViewById(R.id.menuGrid);
323

    
324
    mMenuPopup = new PopupWindow(act);
325
    mMenuPopup.setContentView(layout);
326
    mMenuPopup.setFocusable(true);
327
    int margin  = (int)(width*RubikActivity.MARGIN);
328
    int padding = (int)(width*RubikActivity.PADDING);
329

    
330
    mMenuLayoutWidth = (int)(width/2);
331
    mMenuLayoutHeight= (int)(2*margin + NUM_BUTTONS*(mMenuItemSize+margin));
332

    
333
    LinearLayout.LayoutParams p = new LinearLayout.LayoutParams( mMenuLayoutWidth - 2*padding, (int)mMenuItemSize);
334

    
335
    for(int i=0; i<NUM_BUTTONS; i++)
336
      {
337
      final int but = i;
338
      Button button = new Button(act);
339
      button.setLayoutParams(p);
340
      button.setText(BUTTON_LABELS[i]);
341
      button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
342

    
343
      button.setOnClickListener( new View.OnClickListener()
344
        {
345
        @Override
346
        public void onClick(View v)
347
          {
348
          mMenuPopup.dismiss();
349
          MenuAction(act,but);
350
          }
351
        });
352

    
353
      menuLayout.addView(button);
354
      }
355
    }
356

    
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358

    
359
  private void setupPlayWindow(final RubikActivity act, final float width)
360
    {
361
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
362
    final View layout = layoutInflater.inflate(R.layout.popup_play, null);
363
    mPlayLayout = layout.findViewById(R.id.playGrid);
364

    
365
    mPlayLayoutWidth = (int)(width*0.4f);
366

    
367
    mPlayPopup = new PopupWindow(act);
368
    mPlayPopup.setContentView(layout);
369
    mPlayPopup.setFocusable(true);
370

    
371
    adjustLevels(act);
372
    }
373

    
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375

    
376
  private void MenuAction(RubikActivity act, int button)
377
    {
378
    switch(button)
379
      {
380
      case 0: Bundle sBundle = new Bundle();
381
              sBundle.putInt("tab", mObject.ordinal() );
382
              sBundle.putBoolean("submitting", false);
383
              RubikDialogScores scores = new RubikDialogScores();
384
              scores.setArguments(sBundle);
385
              scores.show(act.getSupportFragmentManager(), null);
386
              break;
387
      case 1: RubikDialogPattern pDiag = new RubikDialogPattern();
388
              pDiag.show( act.getSupportFragmentManager(), RubikDialogPattern.getDialogTag() );
389
              break;
390
      case 2: ScreenList.switchScreen(act, ScreenList.SVER);
391
              break;
392
      case 3: RubikDialogTutorial tDiag = new RubikDialogTutorial();
393
              tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
394
              break;
395
      case 4: RubikDialogAbout aDiag = new RubikDialogAbout();
396
              aDiag.show(act.getSupportFragmentManager(), null);
397
              break;
398
      }
399
    }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
  void setupDetailsButton(final RubikActivity act)
404
    {
405
    int butWidth = 100;
406
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_solve_new,R.drawable.ui_medium_cube_solve_new, R.drawable.ui_big_cube_solve_new, R.drawable.ui_huge_cube_solve_new);
407
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(butWidth,LinearLayout.LayoutParams.MATCH_PARENT);
408
    mDetailsButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
409

    
410
    mDetailsButton.setOnClickListener( new View.OnClickListener()
411
      {
412
      @Override
413
      public void onClick(View v)
414
        {
415
        android.util.Log.e("D", "DETAILS CLICKED!!");
416
        }
417
      });
418
    }
419

    
420
///////////////////////////////////////////////////////////////////////////////////////////////////
421

    
422
  void setupSolveButton(final RubikActivity act)
423
    {
424
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_solve_new,R.drawable.ui_medium_cube_solve_new, R.drawable.ui_big_cube_solve_new, R.drawable.ui_huge_cube_solve_new);
425
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
426
    mSolveButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_END,params);
427

    
428
    mSolveButton.setOnClickListener( new View.OnClickListener()
429
      {
430
      @Override
431
      public void onClick(View v)
432
        {
433
        act.getControl().solveObject();
434
        mMovesController.clearMoves(act);
435
        }
436
      });
437
    }
438

    
439
///////////////////////////////////////////////////////////////////////////////////////////////////
440

    
441
  private void setupScrambleButton(final RubikActivity act)
442
    {
443
    int icon = RubikActivity.getDrawable(R.drawable.ui_small_cube_scramble_new,R.drawable.ui_medium_cube_scramble_new, R.drawable.ui_big_cube_scramble_new, R.drawable.ui_huge_cube_scramble_new);
444
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
445
    mScrambleButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_START, params);
446

    
447
    mScrambleButton.setOnClickListener( new View.OnClickListener()
448
      {
449
      @Override
450
      public void onClick(View v)
451
        {
452
        RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
453
        int numScrambles = play.getObject().getNumScramble();
454
        mShouldReactToEndOfScrambling = false;
455
        act.getControl().scrambleObject(numScrambles);
456
        }
457
      });
458
    }
459

    
460
///////////////////////////////////////////////////////////////////////////////////////////////////
461

    
462
  public void savePreferences(SharedPreferences.Editor editor)
463
    {
464
    editor.putString("statePlay_objName", mObject.name() );
465

    
466
    if( mObjectPopup!=null )
467
      {
468
      mObjectPopup.dismiss();
469
      mObjectPopup = null;
470
      }
471

    
472
    if( mMenuPopup!=null )
473
      {
474
      mMenuPopup.dismiss();
475
      mMenuPopup = null;
476
      }
477

    
478
    if( mPlayPopup!=null )
479
      {
480
      mPlayPopup.dismiss();
481
      mPlayPopup = null;
482
      }
483
    }
484

    
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486

    
487
  public void restorePreferences(SharedPreferences preferences)
488
    {
489
    String objName= preferences.getString("statePlay_objName", DEF_OBJECT.name() );
490
    int ordinal = ObjectType.getOrdinal(objName);
491
    mObject = ordinal>=0 && ordinal<NUM_OBJECTS ? ObjectType.values()[ordinal] : DEF_OBJECT;
492
    }
493

    
494
///////////////////////////////////////////////////////////////////////////////////////////////////
495

    
496
  public boolean setObject(RubikActivity act, ObjectType obj)
497
    {
498
    if( mObject!=obj )
499
      {
500
      mObject = obj;
501
      if( mPlayLayout!=null ) adjustLevels(act);
502
      return true;
503
      }
504

    
505
    return false;
506
    }
507

    
508
///////////////////////////////////////////////////////////////////////////////////////////////////
509
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
510

    
511
  private void displayPopup(RubikActivity act, View view, PopupWindow window, int w, int h, int xoff, int yoff)
512
    {
513
    View topLayout = act.findViewById(R.id.relativeLayout);
514
    boolean isFullScreen;
515

    
516
    if( topLayout!=null )
517
      {
518
      topLayout.getLocationOnScreen(mLocation);
519
      isFullScreen = (mLocation[1]==0);
520
      }
521
    else
522
      {
523
      isFullScreen = true;
524
      }
525

    
526
    try
527
      {
528
      // if on Android 11 or we are fullscreen
529
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || isFullScreen )
530
        {
531
        window.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
532
        window.update(view, w, h);
533
        }
534
      else  // Android 10 or below in pop-up mode or split-screen mode
535
        {
536
        view.getLocationOnScreen(mLocation);
537
        int width  = view.getWidth();
538
        int height = view.getHeight();
539
        int x = mLocation[0]+(width-w)/2;
540
        int y = mLocation[1]+height+yoff;
541

    
542
        window.showAsDropDown(view);
543
        window.update(x,y,w,h);
544
        }
545
      }
546
    catch( IllegalArgumentException iae )
547
      {
548
      // ignore, this means window is 'not attached to window manager' -
549
      // which most probably is because we are already exiting the app.
550
      }
551
    }
552

    
553
///////////////////////////////////////////////////////////////////////////////////////////////////
554

    
555
  public void adjustSolvedIcons()
556
    {
557
    int dbLevel = getDBLevel(mObject);
558
    int numLevel = Math.min(dbLevel, LEVELS_SHOWN);
559
    RubikScores scores = RubikScores.getInstance();
560

    
561
    for(int i=0; i<numLevel; i++)
562
      {
563
      int level = i<numLevel-1 ? i+1 : dbLevel;
564
      Button button = (Button)mPlayLayout.getChildAt(i);
565
      int icon = scores.isSolved(mObject.ordinal(), level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
566
      button.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
567
      }
568
    }
569

    
570
///////////////////////////////////////////////////////////////////////////////////////////////////
571

    
572
  private void adjustLevels(final RubikActivity act)
573
    {
574
    int dbLevel = getDBLevel(mObject);
575
    int numScrambles = mObject.getNumScramble();
576
    int numLevel = Math.min(dbLevel, LEVELS_SHOWN);
577
    String[] levels = new String[numLevel];
578

    
579
    for(int i=0; i<numLevel-1; i++)
580
      {
581
      levels[i] = act.getString(R.string.lv_placeholder,i+1);
582
      }
583

    
584
    if( numLevel>0 )
585
      {
586
      levels[numLevel-1] = act.getString(R.string.level_full);
587
      }
588

    
589
    if( mLevelValue>dbLevel || mLevelValue<1 ||
590
       (mLevelValue<dbLevel || mLevelValue>LEVELS_SHOWN ) )
591
      {
592
      mLevelValue=1;
593
      }
594

    
595
    float width  = act.getScreenWidthInPixels();
596
    int margin   = (int)(width*RubikActivity.MARGIN);
597
    int padding  = (int)(width*RubikActivity.PADDING);
598
    int butWidth = mPlayLayoutWidth - 2*padding;
599
    int butHeight= (int)mMenuItemSize;
600
    int lastButH = (int)(mMenuItemSize*LAST_BUTTON) ;
601

    
602
    LinearLayout.LayoutParams pM = new LinearLayout.LayoutParams( butWidth, butHeight );
603
    pM.setMargins(margin, 0, margin, margin);
604
    LinearLayout.LayoutParams pT = new LinearLayout.LayoutParams( butWidth, butHeight );
605
    pT.setMargins(margin, margin, margin, margin);
606
    LinearLayout.LayoutParams pB = new LinearLayout.LayoutParams( butWidth, lastButH  );
607
    pB.setMargins(margin, margin, margin, 2*margin);
608

    
609
    mPlayLayout.removeAllViews();
610

    
611
    RubikScores scores = RubikScores.getInstance();
612

    
613
    for(int i=0; i<numLevel; i++)
614
      {
615
      final int level     = i<numLevel-1 ? i+1 : dbLevel;
616
      final int scrambles = i<numLevel-1 ? i+1 : numScrambles;
617
      Button button = new Button(act);
618
      button.setLayoutParams(i==0 ? pT : (i==numLevel-1 ? pB : pM));
619
      button.setText(levels[i]);
620
      button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
621

    
622
      int icon = scores.isSolved(mObject.ordinal(), level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
623
      button.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
624

    
625
      button.setOnClickListener( new View.OnClickListener()
626
        {
627
        @Override
628
        public void onClick(View v)
629
          {
630
          ObjectControl control = act.getControl();
631

    
632
          if(control.isUINotBlocked())
633
            {
634
            if( mPlayPopup!=null ) mPlayPopup.dismiss();
635
            mLevelValue = level;
636
            mShouldReactToEndOfScrambling = true;
637
            control.scrambleObject(scrambles);
638
            }
639
          }
640
        });
641

    
642
      mPlayLayout.addView(button);
643
      }
644
    }
645

    
646
///////////////////////////////////////////////////////////////////////////////////////////////////
647
// historically older versions of the app had lower 'maxScrambles' in case of several objects and
648
// those got remembered in the server-side DB already, so we need to keep using them. This function
649
// provides a map between 'maxScramble' of an object and its 'dbLevel'. All new objects will have
650
// those two values the same.
651

    
652
  public static int getDBLevel(ObjectType object)
653
    {
654
    switch(object)
655
      {
656
      case CUBE_3: return 16;
657
      case CUBE_4: return 20;
658
      case CUBE_5: return 24;
659
      case PYRA_4: return 15;
660
      case PYRA_5: return 20;
661
      case MEGA_5: return 35;
662
      case DIAM_2: return 10;
663
      case DIAM_3: return 18;
664
      case REDI_3: return 14;
665
      case HELI_3: return 18;
666
      case SKEW_3: return 17;
667
      case REX_3 : return 16;
668
      case MIRR_3: return 16;
669
      default    : return object.getNumScramble();
670
      }
671
    }
672

    
673
///////////////////////////////////////////////////////////////////////////////////////////////////
674

    
675
  public int getLevel()
676
    {
677
    return mLevelValue;
678
    }
679

    
680
///////////////////////////////////////////////////////////////////////////////////////////////////
681

    
682
  public boolean shouldReactToEndOfScrambling()
683
    {
684
    return mShouldReactToEndOfScrambling;
685
    }
686

    
687
///////////////////////////////////////////////////////////////////////////////////////////////////
688

    
689
  public ObjectType getObject()
690
    {
691
    return mObject;
692
    }
693
  }
(5-5/10)