Project

General

Profile

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

magiccube / src / main / java / org / distorted / screens / RubikScreenPlay.java @ 8d1da3f1

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.view.ViewGroup;
33
import android.widget.Button;
34
import android.widget.GridLayout;
35
import android.widget.ImageButton;
36
import android.widget.LinearLayout;
37
import android.widget.PopupWindow;
38

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

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

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

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

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

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

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

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

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

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

    
97
    MAX_LEVEL = max;
98
    }
99

    
100
///////////////////////////////////////////////////////////////////////////////////////////////////
101

    
102
  void leaveScreen(RubikActivity act)
103
    {
104

    
105
    }
106

    
107
///////////////////////////////////////////////////////////////////////////////////////////////////
108

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

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

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

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

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

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

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

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

    
139
//////////////////////////////////////////////////////////////////////////////////////////////////
140

    
141
  private void setupObjectButton(final RubikActivity act, final float width)
142
    {
143
    final int margin  = (int)(width*RubikActivity.MARGIN);
144
    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);
145
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
146
    mObjButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
147

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

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

    
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

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

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

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

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

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

    
208
  private void setupMenuButton(final RubikActivity act, final float width)
209
    {
210
    final int margin = (int)(width*RubikActivity.MARGIN);
211
    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);
212
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
213
    mMenuButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_MIDDLE, params);
214

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

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

    
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237

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

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

    
249
    LinearLayout view = (LinearLayout)inflate( act, R.layout.popup_object, 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
    setupBottomLayout(act,bottomLayout,2*mObjectSize,mObjectSize);
260

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

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

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

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

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

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

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

    
309
      nextInRow[row]++;
310

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

    
315
///////////////////////////////////////////////////////////////////////////////////////////////////
316

    
317
  private void setupBottomLayout(final RubikActivity act, final LinearLayout layout, int width, int height)
318
    {
319
    int iconD = RubikActivity.getDrawable(R.drawable.ui_small_info,R.drawable.ui_medium_info, R.drawable.ui_big_info, R.drawable.ui_huge_info);
320
    int iconT = RubikActivity.getDrawable(R.drawable.ui_small_tutorial,R.drawable.ui_medium_tutorial, R.drawable.ui_big_tutorial, R.drawable.ui_huge_tutorial);
321

    
322
    ImageButton buttonTut = layout.findViewById(R.id.buttonTut);
323
         Button buttonNul = layout.findViewById(R.id.buttonNul);
324
    ImageButton buttonDet = layout.findViewById(R.id.buttonDet);
325

    
326
    buttonTut.setImageResource(iconT);
327
    buttonDet.setImageResource(iconD);
328
    buttonNul.setVisibility(View.INVISIBLE);
329

    
330
    buttonNul.setWidth(width);
331

    
332
    TypedValue outValue = new TypedValue();
333
    act.getTheme().resolveAttribute(android.R.attr.selectableItemBackgroundBorderless, outValue, true);
334
    buttonTut.setBackgroundResource(outValue.resourceId);
335
    buttonDet.setBackgroundResource(outValue.resourceId);
336

    
337
    buttonTut.setOnClickListener( new View.OnClickListener()
338
      {
339
      @Override
340
      public void onClick(View v)
341
        {
342
        if( mObjectPopup!=null ) mObjectPopup.dismiss();
343
        RubikDialogTutorial tDiag = new RubikDialogTutorial();
344
        tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
345
        }
346
      });
347

    
348
    buttonDet.setOnClickListener( new View.OnClickListener()
349
      {
350
      @Override
351
      public void onClick(View v)
352
        {
353
        android.util.Log.e("D", "BUTTON DET CLICKED!!");
354
        }
355
      });
356
    }
357

    
358
///////////////////////////////////////////////////////////////////////////////////////////////////
359

    
360
  private void setupMenuWindow(final RubikActivity act, final float width)
361
    {
362
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
363
    final View layout = layoutInflater.inflate(R.layout.popup_menu, null);
364
    LinearLayout menuLayout = layout.findViewById(R.id.menuGrid);
365

    
366
    mMenuPopup = new PopupWindow(act);
367
    mMenuPopup.setContentView(layout);
368
    mMenuPopup.setFocusable(true);
369
    int margin  = (int)(width*RubikActivity.MARGIN);
370
    int padding = (int)(width*RubikActivity.PADDING);
371

    
372
    mMenuLayoutWidth = (int)(width/2);
373
    mMenuLayoutHeight= (int)(2*margin + NUM_BUTTONS*(mMenuItemSize+margin));
374

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

    
377
    for(int i=0; i<NUM_BUTTONS; i++)
378
      {
379
      final int but = i;
380
      Button button = new Button(act);
381
      button.setLayoutParams(p);
382
      button.setText(BUTTON_LABELS[i]);
383
      button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
384

    
385
      button.setOnClickListener( new View.OnClickListener()
386
        {
387
        @Override
388
        public void onClick(View v)
389
          {
390
          mMenuPopup.dismiss();
391
          MenuAction(act,but);
392
          }
393
        });
394

    
395
      menuLayout.addView(button);
396
      }
397
    }
398

    
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400

    
401
  private void setupPlayWindow(final RubikActivity act, final float width)
402
    {
403
    LayoutInflater layoutInflater = (LayoutInflater)act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
404
    final View layout = layoutInflater.inflate(R.layout.popup_play, null);
405
    mPlayLayout = layout.findViewById(R.id.playGrid);
406

    
407
    mPlayLayoutWidth = (int)(width*0.4f);
408

    
409
    mPlayPopup = new PopupWindow(act);
410
    mPlayPopup.setContentView(layout);
411
    mPlayPopup.setFocusable(true);
412

    
413
    adjustLevels(act);
414
    }
415

    
416
///////////////////////////////////////////////////////////////////////////////////////////////////
417

    
418
  private void MenuAction(RubikActivity act, int button)
419
    {
420
    switch(button)
421
      {
422
      case 0: Bundle sBundle = new Bundle();
423
              sBundle.putInt("tab", mObject.ordinal() );
424
              sBundle.putBoolean("submitting", false);
425
              RubikDialogScores scores = new RubikDialogScores();
426
              scores.setArguments(sBundle);
427
              scores.show(act.getSupportFragmentManager(), null);
428
              break;
429
      case 1: RubikDialogPattern pDiag = new RubikDialogPattern();
430
              pDiag.show( act.getSupportFragmentManager(), RubikDialogPattern.getDialogTag() );
431
              break;
432
      case 2: ScreenList.switchScreen(act, ScreenList.SVER);
433
              break;
434
      case 3: RubikDialogTutorial tDiag = new RubikDialogTutorial();
435
              tDiag.show( act.getSupportFragmentManager(), RubikDialogTutorial.getDialogTag() );
436
              break;
437
      case 4: RubikDialogAbout aDiag = new RubikDialogAbout();
438
              aDiag.show(act.getSupportFragmentManager(), null);
439
              break;
440
      }
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444

    
445
  void setupSolveButton(final RubikActivity act)
446
    {
447
    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);
448
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
449
    mSolveButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_END,params);
450

    
451
    mSolveButton.setOnClickListener( new View.OnClickListener()
452
      {
453
      @Override
454
      public void onClick(View v)
455
        {
456
        act.getControl().solveObject();
457
        mMovesController.clearMoves(act);
458
        }
459
      });
460
    }
461

    
462
///////////////////////////////////////////////////////////////////////////////////////////////////
463

    
464
  private void setupScrambleButton(final RubikActivity act)
465
    {
466
    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);
467
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
468
    mScrambleButton = new TransparentImageButton(act, icon, TransparentImageButton.GRAVITY_START, params);
469

    
470
    mScrambleButton.setOnClickListener( new View.OnClickListener()
471
      {
472
      @Override
473
      public void onClick(View v)
474
        {
475
        RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
476
        int numScrambles = play.getObject().getNumScramble();
477
        mShouldReactToEndOfScrambling = false;
478
        act.getControl().scrambleObject(numScrambles);
479
        }
480
      });
481
    }
482

    
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

    
485
  public void savePreferences(SharedPreferences.Editor editor)
486
    {
487
    editor.putString("statePlay_objName", mObject.name() );
488

    
489
    if( mObjectPopup!=null )
490
      {
491
      mObjectPopup.dismiss();
492
      mObjectPopup = null;
493
      }
494

    
495
    if( mMenuPopup!=null )
496
      {
497
      mMenuPopup.dismiss();
498
      mMenuPopup = null;
499
      }
500

    
501
    if( mPlayPopup!=null )
502
      {
503
      mPlayPopup.dismiss();
504
      mPlayPopup = null;
505
      }
506
    }
507

    
508
///////////////////////////////////////////////////////////////////////////////////////////////////
509

    
510
  public void restorePreferences(SharedPreferences preferences)
511
    {
512
    String objName= preferences.getString("statePlay_objName", DEF_OBJECT.name() );
513
    int ordinal = ObjectType.getOrdinal(objName);
514
    mObject = ordinal>=0 && ordinal<NUM_OBJECTS ? ObjectType.values()[ordinal] : DEF_OBJECT;
515
    }
516

    
517
///////////////////////////////////////////////////////////////////////////////////////////////////
518

    
519
  public boolean setObject(RubikActivity act, ObjectType obj)
520
    {
521
    if( mObject!=obj )
522
      {
523
      mObject = obj;
524
      if( mPlayLayout!=null ) adjustLevels(act);
525
      return true;
526
      }
527

    
528
    return false;
529
    }
530

    
531
///////////////////////////////////////////////////////////////////////////////////////////////////
532
// work around lame bugs in Android's version <= 10 pop-up and split-screen modes
533

    
534
  private void displayPopup(RubikActivity act, View view, PopupWindow window, int w, int h, int xoff, int yoff)
535
    {
536
    View topLayout = act.findViewById(R.id.relativeLayout);
537
    boolean isFullScreen;
538

    
539
    if( topLayout!=null )
540
      {
541
      topLayout.getLocationOnScreen(mLocation);
542
      isFullScreen = (mLocation[1]==0);
543
      }
544
    else
545
      {
546
      isFullScreen = true;
547
      }
548

    
549
    try
550
      {
551
      // if on Android 11 or we are fullscreen
552
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R || isFullScreen )
553
        {
554
        window.showAsDropDown(view, xoff, yoff, Gravity.CENTER);
555
        window.update(view, w, h);
556
        }
557
      else  // Android 10 or below in pop-up mode or split-screen mode
558
        {
559
        view.getLocationOnScreen(mLocation);
560
        int width  = view.getWidth();
561
        int height = view.getHeight();
562
        int x = mLocation[0]+(width-w)/2;
563
        int y = mLocation[1]+height+yoff;
564

    
565
        window.showAsDropDown(view);
566
        window.update(x,y,w,h);
567
        }
568
      }
569
    catch( IllegalArgumentException iae )
570
      {
571
      // ignore, this means window is 'not attached to window manager' -
572
      // which most probably is because we are already exiting the app.
573
      }
574
    }
575

    
576
///////////////////////////////////////////////////////////////////////////////////////////////////
577

    
578
  public void adjustSolvedIcons()
579
    {
580
    int dbLevel = getDBLevel(mObject);
581
    int numLevel = Math.min(dbLevel, LEVELS_SHOWN);
582
    RubikScores scores = RubikScores.getInstance();
583

    
584
    for(int i=0; i<numLevel; i++)
585
      {
586
      int level = i<numLevel-1 ? i+1 : dbLevel;
587
      Button button = (Button)mPlayLayout.getChildAt(i);
588
      int icon = scores.isSolved(mObject.ordinal(), level-1) ? R.drawable.ui_solved : R.drawable.ui_notsolved;
589
      button.setCompoundDrawablesWithIntrinsicBounds(icon,0,0,0);
590
      }
591
    }
592

    
593
///////////////////////////////////////////////////////////////////////////////////////////////////
594

    
595
  private void adjustLevels(final RubikActivity act)
596
    {
597
    int dbLevel = getDBLevel(mObject);
598
    int numScrambles = mObject.getNumScramble();
599
    int numLevel = Math.min(dbLevel, LEVELS_SHOWN);
600
    String[] levels = new String[numLevel];
601

    
602
    for(int i=0; i<numLevel-1; i++)
603
      {
604
      levels[i] = act.getString(R.string.lv_placeholder,i+1);
605
      }
606

    
607
    if( numLevel>0 )
608
      {
609
      levels[numLevel-1] = act.getString(R.string.level_full);
610
      }
611

    
612
    if( mLevelValue>dbLevel || mLevelValue<1 ||
613
       (mLevelValue<dbLevel || mLevelValue>LEVELS_SHOWN ) )
614
      {
615
      mLevelValue=1;
616
      }
617

    
618
    float width  = act.getScreenWidthInPixels();
619
    int margin   = (int)(width*RubikActivity.MARGIN);
620
    int padding  = (int)(width*RubikActivity.PADDING);
621
    int butWidth = mPlayLayoutWidth - 2*padding;
622
    int butHeight= (int)mMenuItemSize;
623
    int lastButH = (int)(mMenuItemSize*LAST_BUTTON) ;
624

    
625
    LinearLayout.LayoutParams pM = new LinearLayout.LayoutParams( butWidth, butHeight );
626
    pM.setMargins(margin, 0, margin, margin);
627
    LinearLayout.LayoutParams pT = new LinearLayout.LayoutParams( butWidth, butHeight );
628
    pT.setMargins(margin, margin, margin, margin);
629
    LinearLayout.LayoutParams pB = new LinearLayout.LayoutParams( butWidth, lastButH  );
630
    pB.setMargins(margin, margin, margin, 2*margin);
631

    
632
    mPlayLayout.removeAllViews();
633

    
634
    RubikScores scores = RubikScores.getInstance();
635

    
636
    for(int i=0; i<numLevel; i++)
637
      {
638
      final int level     = i<numLevel-1 ? i+1 : dbLevel;
639
      final int scrambles = i<numLevel-1 ? i+1 : numScrambles;
640
      Button button = new Button(act);
641
      button.setLayoutParams(i==0 ? pT : (i==numLevel-1 ? pB : pM));
642
      button.setText(levels[i]);
643
      button.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMenuTextSize);
644

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

    
648
      button.setOnClickListener( new View.OnClickListener()
649
        {
650
        @Override
651
        public void onClick(View v)
652
          {
653
          ObjectControl control = act.getControl();
654

    
655
          if(control.isUINotBlocked())
656
            {
657
            if( mPlayPopup!=null ) mPlayPopup.dismiss();
658
            mLevelValue = level;
659
            mShouldReactToEndOfScrambling = true;
660
            control.scrambleObject(scrambles);
661
            }
662
          }
663
        });
664

    
665
      mPlayLayout.addView(button);
666
      }
667
    }
668

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

    
675
  public static int getDBLevel(ObjectType object)
676
    {
677
    switch(object)
678
      {
679
      case CUBE_3: return 16;
680
      case CUBE_4: return 20;
681
      case CUBE_5: return 24;
682
      case PYRA_4: return 15;
683
      case PYRA_5: return 20;
684
      case MEGA_5: return 35;
685
      case DIAM_2: return 10;
686
      case DIAM_3: return 18;
687
      case REDI_3: return 14;
688
      case HELI_3: return 18;
689
      case SKEW_3: return 17;
690
      case REX_3 : return 16;
691
      case MIRR_3: return 16;
692
      default    : return object.getNumScramble();
693
      }
694
    }
695

    
696
///////////////////////////////////////////////////////////////////////////////////////////////////
697

    
698
  public int getLevel()
699
    {
700
    return mLevelValue;
701
    }
702

    
703
///////////////////////////////////////////////////////////////////////////////////////////////////
704

    
705
  public boolean shouldReactToEndOfScrambling()
706
    {
707
    return mShouldReactToEndOfScrambling;
708
    }
709

    
710
///////////////////////////////////////////////////////////////////////////////////////////////////
711

    
712
  public ObjectType getObject()
713
    {
714
    return mObject;
715
    }
716
  }
(5-5/10)