Project

General

Profile

Download (31.3 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / json / JsonReader.java @ 9554f5d4

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted 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
// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.objectlib.json;
21

    
22
import java.io.BufferedReader;
23
import java.io.File;
24
import java.io.FileInputStream;
25
import java.io.FileNotFoundException;
26
import java.io.IOException;
27
import java.io.InputStream;
28
import java.io.InputStreamReader;
29
import java.nio.charset.StandardCharsets;
30

    
31
import android.content.Context;
32

    
33
import org.distorted.objectlib.helpers.ObjectFaceShape;
34
import org.json.JSONArray;
35
import org.json.JSONException;
36
import org.json.JSONObject;
37

    
38
import org.distorted.library.type.Static3D;
39
import org.distorted.library.type.Static4D;
40

    
41
import org.distorted.objectlib.helpers.ObjectShape;
42
import org.distorted.objectlib.helpers.ObjectSticker;
43
import org.distorted.objectlib.scrambling.ScrambleState;
44
import org.distorted.objectlib.main.ObjectType;
45

    
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

    
48
public class JsonReader
49
{
50
  private ScrambleState[] mStates;
51
  private int[][] mSolvedQuats;
52
  private Static4D[] mQuats;
53
  private int mSolvedFuncIndex;
54
  private int mNumStickerTypes;
55
  private float[][] mCuts;
56
  private boolean[][] mLayerRotatable;
57
  private int mMovementType, mMovementSplit;
58
  private int[][][] mEnabled;
59
  private float[] mDist3D;
60
  private int mNumCubitFaces, mNumFaces, mNumFaceColors;
61
  private float[][] mPositions;
62
  private ObjectShape[] mShapes;
63
  private ObjectFaceShape[] mFaceShapes;
64
  private Static4D[] mCubitQuats;
65
  private int mNumCubitVariants;
66
  private int[] mCubitVariant;
67
  private int[][] mVariantFaceColor, mCubitFaceColor;
68
  private ObjectSticker[] mObjectSticker;
69
  private Static3D[] mAxis;
70
  private int[] mBasicAngle;
71
  private String mLongName, mShortName, mInventor;
72
  private int mYearOfInvention, mComplexity;
73
  private int[] mNumLayers;
74
  private float mSize;
75
  private int mScrambleType, mNumScrambles;
76
  private int[] mColor;
77
  private int mInternalColor;
78
  private boolean mResetMaps;
79
  private String mTutorialObject;
80
  private String[][] mTutorials;
81
  private long mSignature;
82

    
83
  private static JsonReader mThis;
84

    
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86

    
87
  private JsonReader()
88
    {
89
    }
90

    
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92

    
93
  public static JsonReader getInstance()
94
    {
95
    if( mThis==null ) mThis = new JsonReader();
96
    return mThis;
97
    }
98

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

    
101
  private void parseMetadata(JSONObject object) throws JSONException
102
    {
103
    mLongName        = object.getString("longname");
104
    mShortName       = object.getString("shortname");
105
    mInventor        = object.getString("inventor");
106
    mYearOfInvention = object.getInt("year");
107
    mComplexity      = object.getInt("complexity");
108
    mSize            = (float)object.getDouble("size");
109
    mNumScrambles    = object.getInt("scrambles");
110
    mResetMaps       = object.getBoolean("resetmaps");
111
    mNumFaces        = object.getInt("num_faces");
112

    
113
    try
114
      {
115
      mSignature = object.getLong("signature");
116
      }
117
    catch(JSONException ex)
118
      {
119
      // objects older than Feb 2022 do not have the 'signature' field. They all use the ObjectType.ordinal
120
      // as their signature.
121
      mSignature = ObjectType.getOrdinal(mShortName);
122
      }
123
    }
124

    
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126

    
127
  private void parseCubits(JSONArray object) throws JSONException
128
    {
129
    int numCubits = object.length();
130

    
131
    mCubitQuats     = new Static4D[numCubits];
132
    mCubitVariant   = new int[numCubits];
133
    mPositions      = new float[numCubits][];
134
    mCubitFaceColor = new int[numCubits][];
135

    
136
    for(int i=0; i<numCubits; i++)
137
      {
138
      JSONObject jsonCubit = object.getJSONObject(i);
139

    
140
      float qx = (float)jsonCubit.getDouble("qx");
141
      float qy = (float)jsonCubit.getDouble("qy");
142
      float qz = (float)jsonCubit.getDouble("qz");
143
      float qw = (float)jsonCubit.getDouble("qw");
144

    
145
      mCubitQuats[i] = new Static4D(qx,qy,qz,qw);
146
      mCubitVariant[i] = jsonCubit.getInt("variant");
147

    
148
      JSONArray jsonCenter = jsonCubit.getJSONArray("centers");
149
      int numCenter = jsonCenter.length();
150
      mPositions[i] = new float[numCenter];
151
      for(int j=0; j<numCenter; j++) mPositions[i][j] = (float)jsonCenter.getDouble(j);
152

    
153
      JSONArray jsonColor  = jsonCubit.getJSONArray("colors");
154
      int numColor = jsonColor.length();
155
      mCubitFaceColor[i] = new int[numColor];
156
      for(int j=0; j<numColor; j++) mCubitFaceColor[i][j] = jsonColor.getInt(j);
157
      }
158
    }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

    
162
  private void parseShapes(JSONArray object) throws JSONException
163
    {
164
    mNumCubitVariants = object.length();
165
    mVariantFaceColor = new int[mNumCubitVariants][];
166
    mShapes     = new ObjectShape[mNumCubitVariants];
167
    mFaceShapes = new ObjectFaceShape[mNumCubitVariants];
168
    float[][][] verts     = new float[mNumCubitVariants][][];
169
    float[][][] bands     = new float[mNumCubitVariants][][];
170
    float[][][] corners   = new float[mNumCubitVariants][][];
171
    float[][][] centers   = new float[mNumCubitVariants][][];
172
    float[][] convexity   = new float[mNumCubitVariants][];
173
    int[][] cornerIndices = new int[mNumCubitVariants][];
174
    int[][] centerIndices = new int[mNumCubitVariants][];
175
    int[][] bandIndices   = new int[mNumCubitVariants][];
176
    int[][][] vertIndices = new int[mNumCubitVariants][][];
177

    
178
    mNumCubitFaces = -1;
179

    
180
    for(int i=0; i<mNumCubitVariants; i++)
181
      {
182
      JSONObject jsonShape = object.getJSONObject(i);
183

    
184
      ////// vertices /////////////////////////////////////////////////
185
      JSONArray jsonVertices= jsonShape.getJSONArray("vertices");
186
      int numVertices = jsonVertices.length();
187
      verts[i] = new float[numVertices][3];
188
      cornerIndices[i] = new int[numVertices];
189
      centerIndices[i] = new int[numVertices];
190

    
191
      for(int j=0; j<numVertices; j++)
192
        {
193
        JSONObject vert = jsonVertices.getJSONObject(j);
194
        verts[i][j][0] = (float)vert.getDouble("x");
195
        verts[i][j][1] = (float)vert.getDouble("y");
196
        verts[i][j][2] = (float)vert.getDouble("z");
197
        cornerIndices[i][j] = vert.getInt("cornerIndex");
198
        centerIndices[i][j] = vert.getInt("centerIndex");
199
        }
200

    
201
      ////// faces ////////////////////////////////////////////////////
202
      JSONArray jsonFaces= jsonShape.getJSONArray("faces");
203
      int numFaces = jsonFaces.length();
204
      mVariantFaceColor[i] = new int[numFaces];
205
      bandIndices[i] = new int[numFaces];
206
      vertIndices[i] = new int[numFaces][];
207

    
208
      if( mNumCubitFaces<numFaces ) mNumCubitFaces=numFaces;
209

    
210
      for(int j=0; j<numFaces; j++)
211
        {
212
        JSONObject jsonFace = jsonFaces.getJSONObject(j);
213
        mVariantFaceColor[i][j] = jsonFace.getInt("sticker");
214
        bandIndices[i][j] = jsonFace.getInt("bandIndex");
215
        JSONArray vertices = jsonFace.getJSONArray("vertexIndices");
216
        int numV = vertices.length();
217
        vertIndices[i][j] = new int[numV];
218
        for(int k=0; k<numV; k++) vertIndices[i][j][k] = vertices.getInt(k);
219
        }
220

    
221
      ////// bands ////////////////////////////////////////////////////
222
      JSONArray jsonBands= jsonShape.getJSONArray("bands");
223
      int numBands = jsonBands.length();
224
      bands[i] = new float[numBands][7];
225

    
226
      for(int j=0; j<numBands; j++)
227
        {
228
        JSONObject jsonBand = jsonBands.getJSONObject(j);
229

    
230
        bands[i][j][0] = (float)jsonBand.getDouble("height");
231
        bands[i][j][1] = (float)jsonBand.getDouble("angle");
232
        bands[i][j][2] = (float)jsonBand.getDouble("distanceToCenter");
233
        bands[i][j][3] = (float)jsonBand.getDouble("distanceToFlat");
234
        bands[i][j][4] = (float)jsonBand.getDouble("numOfBands");
235
        bands[i][j][5] = (float)jsonBand.getDouble("extraI");
236
        bands[i][j][6] = (float)jsonBand.getDouble("extraJ");
237
        }
238

    
239
      ////// cornerPush ///////////////////////////////////////////////
240
      JSONArray jsonCornerPush= jsonShape.optJSONArray("cornerPush");
241

    
242
      if( jsonCornerPush!=null )
243
        {
244
        int numCornerP = jsonCornerPush.length();
245
        corners[i] = new float[numCornerP][2];
246

    
247
        for(int j=0; j<numCornerP; j++)
248
          {
249
          JSONObject jsonC = jsonCornerPush.getJSONObject(j);
250
          corners[i][j][0] = (float)jsonC.getDouble("strength");
251
          corners[i][j][1] = (float)jsonC.getDouble("radius");
252
          }
253
        }
254

    
255
      ////// centerPush ///////////////////////////////////////////////
256
      JSONArray jsonCenterPush= jsonShape.optJSONArray("centerPush");
257

    
258
      if( jsonCenterPush!=null )
259
        {
260
        int numCenterP = jsonCenterPush.length();
261
        centers[i] = new float[numCenterP][3];
262

    
263
        for(int j=0; j<numCenterP; j++)
264
          {
265
          JSONObject jsonC = jsonCenterPush.getJSONObject(j);
266
          centers[i][j][0] = (float)jsonC.getDouble("x");
267
          centers[i][j][1] = (float)jsonC.getDouble("y");
268
          centers[i][j][2] = (float)jsonC.getDouble("z");
269
          }
270
        }
271

    
272
      ////// convexity ///////////////////////////////////////////////
273
      JSONObject jsonConvexity = jsonShape.optJSONObject("convexity");
274

    
275
      if( jsonConvexity!=null )
276
        {
277
        convexity[i] = new float[3];
278
        convexity[i][0] = (float)jsonConvexity.getDouble("x");
279
        convexity[i][1] = (float)jsonConvexity.getDouble("y");
280
        convexity[i][2] = (float)jsonConvexity.getDouble("z");
281
        }
282
      }
283

    
284
    for(int i=0; i<mNumCubitVariants; i++)
285
      {
286
      mShapes[i] = new ObjectShape(verts[i],vertIndices[i]);
287
      mFaceShapes[i] = new ObjectFaceShape(bands[i],bandIndices[i],corners[i],cornerIndices[i],centers[i],centerIndices[i],convexity[i] );
288
      }
289
    }
290

    
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292

    
293
  private void parseStickers(JSONArray object) throws JSONException
294
    {
295
    mNumStickerTypes = object.length();
296
    mObjectSticker = new ObjectSticker[mNumStickerTypes];
297

    
298
    for(int i=0; i<mNumStickerTypes; i++)
299
      {
300
      JSONObject sticker = object.getJSONObject(i);
301
      float stroke = (float)sticker.getDouble("stroke");
302
      JSONArray vertices = sticker.getJSONArray("vertices");
303
      int numVertices = vertices.length();
304

    
305
      float[] coords     = new float[2*numVertices];
306
      float[] curvatures = new float[numVertices];
307
      float[] radii      = new float[numVertices];
308

    
309
      for(int j=0; j<numVertices; j++)
310
        {
311
        JSONObject vertex = vertices.getJSONObject(j);
312

    
313
        coords[2*j  ] = (float)vertex.getDouble("x");
314
        coords[2*j+1] = (float)vertex.getDouble("y");
315
        curvatures[j] = (float)vertex.getDouble("angle");
316
        radii[j]      = (float)vertex.getDouble("radius");
317
        }
318

    
319
      mObjectSticker[i] = new ObjectSticker(coords,curvatures,radii,stroke);
320
      }
321
    }
322

    
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324

    
325
  private void parseMesh(JSONObject object) throws JSONException
326
    {
327
    JSONArray cubits   = object.getJSONArray("cubits");
328
    parseCubits(cubits);
329
    JSONArray shapes   = object.getJSONArray("shapes");
330
    parseShapes(shapes);
331
    JSONArray stickers = object.getJSONArray("stickers");
332
    parseStickers(stickers);
333
    }
334

    
335
///////////////////////////////////////////////////////////////////////////////////////////////////
336

    
337
  private void parseAxis(JSONArray object) throws JSONException
338
    {
339
    int numAxis = object.length();
340

    
341
    mBasicAngle     = new int[numAxis];
342
    mAxis           = new Static3D[numAxis];
343
    mCuts           = new float[numAxis][];
344
    mLayerRotatable = new boolean[numAxis][];
345
    mNumLayers      = new int[numAxis];
346

    
347
    for(int i=0; i<numAxis; i++)
348
      {
349
      JSONObject jsonAx = object.getJSONObject(i);
350

    
351
      mBasicAngle[i] = jsonAx.getInt("basicAngle");
352

    
353
      float x = (float)jsonAx.getDouble("x");
354
      float y = (float)jsonAx.getDouble("y");
355
      float z = (float)jsonAx.getDouble("z");
356

    
357
      mAxis[i] = new Static3D(x,y,z);
358

    
359
      JSONArray jsonCuts = jsonAx.getJSONArray("cuts");
360
      int numCuts = jsonCuts.length();
361
      mCuts[i] = new float[numCuts];
362
      for(int j=0; j<numCuts; j++) mCuts[i][j] = (float)jsonCuts.getDouble(j);
363

    
364
      JSONArray jsonRota = jsonAx.getJSONArray("rotatable");
365
      int numRota = jsonRota.length();
366
      mLayerRotatable[i] = new boolean[numRota];
367
      for(int j=0; j<numRota; j++) mLayerRotatable[i][j] = jsonRota.getBoolean(j);
368

    
369
      mNumLayers[i] = numRota;
370
      }
371
    }
372

    
373
///////////////////////////////////////////////////////////////////////////////////////////////////
374

    
375
  private void parseQuats(JSONArray object) throws JSONException
376
    {
377
    int numQuats = object.length();
378
    mQuats = new Static4D[numQuats];
379

    
380
    for(int i=0; i<numQuats; i++)
381
      {
382
      JSONObject jsonQuat = object.getJSONObject(i);
383

    
384
      float x = (float)jsonQuat.getDouble("x");
385
      float y = (float)jsonQuat.getDouble("y");
386
      float z = (float)jsonQuat.getDouble("z");
387
      float w = (float)jsonQuat.getDouble("w");
388

    
389
      mQuats[i] = new Static4D(x,y,z,w);
390
      }
391
    }
392

    
393
///////////////////////////////////////////////////////////////////////////////////////////////////
394

    
395
  private void parseScrambling(JSONObject object) throws JSONException
396
    {
397
    mScrambleType = object.getInt("scrambleType");
398

    
399
    if( mScrambleType==0 )
400
      {
401
      JSONArray jsonStates = object.getJSONArray("scrambleStates");
402
      int numStates = jsonStates.length();
403
      mStates = new ScrambleState[numStates];
404

    
405
      for(int i=0; i<numStates; i++)
406
        {
407
        JSONArray jsonState = jsonStates.getJSONArray(i);
408
        int numAxis = jsonState.length();
409
        int[][] scramblingData = new int[numAxis][];
410

    
411
        for(int j=0; j<numAxis; j++)
412
          {
413
          JSONArray jsonData = jsonState.getJSONArray(j);
414
          int numData = jsonData.length();
415
          scramblingData[j] = new int[numData];
416
          for(int k=0; k<numData; k++) scramblingData[j][k] = jsonData.getInt(k);
417
          }
418

    
419
        mStates[i] = new ScrambleState(scramblingData);
420
        }
421
      }
422
    }
423

    
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425

    
426
  private void parseTouchcontrol(JSONObject object) throws JSONException
427
    {
428
    mMovementType = object.getInt("movementType");
429
    mMovementSplit= object.getInt("movementSplit");
430

    
431
    try
432
      {
433
      JSONArray jsonEnabled = object.getJSONArray("enabledAxis");
434
      int numFace = jsonEnabled.length();
435

    
436
      mEnabled = new int[numFace][][];
437

    
438
      for(int i=0; i<numFace; i++)
439
        {
440
        JSONArray jsonSection = jsonEnabled.getJSONArray(i);
441
        int numSection = jsonSection.length();
442
        mEnabled[i] = new int[numSection][];
443

    
444
        for(int j=0; j<numSection; j++)
445
          {
446
          JSONArray jsonAx = jsonSection.getJSONArray(j);
447
          int numAxis = jsonAx.length();
448
          mEnabled[i][j] = new int[numAxis];
449
          for(int k=0; k<numAxis; k++) mEnabled[i][j][k] = jsonAx.getInt(k);
450
          }
451
        }
452
      }
453
    catch( JSONException ex )
454
      {
455
      // ignore, the object does not have to have 'enabledAxis' defined at all.
456
      }
457

    
458
    try
459
      {
460
      JSONArray jsonDist = object.getJSONArray("dist3D");
461
      int num = jsonDist.length();
462
      mDist3D = new float[num];
463
      for(int j=0; j<num; j++) mDist3D[j] = (float)jsonDist.getDouble(j);
464
      }
465
    catch( JSONException ex )
466
      {
467
      // ignore, the object does not have a 'dist3D' which is possible.
468
      }
469
    }
470

    
471
///////////////////////////////////////////////////////////////////////////////////////////////////
472

    
473
  private void parseColors(JSONArray object) throws JSONException
474
    {
475
    mNumFaceColors = object.length()-1;
476

    
477
    mColor = new int[mNumFaceColors];
478
    for(int i=0; i<mNumFaceColors; i++) mColor[i] = object.getInt(i);
479

    
480
    mInternalColor = object.getInt(mNumFaceColors);
481
    }
482

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

    
485
  private void parseSolved(JSONObject solved) throws JSONException
486
    {
487
    mSolvedFuncIndex = solved.getInt("functionIndex");
488

    
489
    try
490
      {
491
      JSONArray groupArray= solved.getJSONArray("groups");
492
      int numGroups = groupArray.length();
493
      mSolvedQuats  = new int[numGroups][];
494

    
495
      for(int i=0; i<numGroups; i++)
496
        {
497
        JSONArray groupElements = groupArray.getJSONArray(i);
498
        int groupSize = groupElements.length();
499
        mSolvedQuats[i] = new int[groupSize];
500
        for(int j=0; j<groupSize; j++) mSolvedQuats[i][j] = groupElements.getInt(j);
501
        }
502
      }
503
    catch( JSONException ex )
504
      {
505
      // ignore, the object does not have to have an array of solved groups.
506
      }
507
    }
508

    
509
///////////////////////////////////////////////////////////////////////////////////////////////////
510

    
511
  private void parseVersion1(JSONObject object) throws JSONException
512
    {
513
    JSONObject metadata    = object.getJSONObject("metadata");
514
    parseMetadata(metadata);
515
    JSONObject mesh        = object.getJSONObject("mesh");
516
    parseMesh(mesh);
517
    JSONArray axis         = object.getJSONArray("axis");
518
    parseAxis(axis);
519
    JSONArray quats        = object.getJSONArray("quats");
520
    parseQuats(quats);
521
    JSONObject scrambling  = object.getJSONObject("scrambling");
522
    parseScrambling(scrambling);
523
    JSONObject touchcontrol= object.getJSONObject("touchcontrol");
524
    parseTouchcontrol(touchcontrol);
525
    JSONArray colors       = object.getJSONArray("colors");
526
    parseColors(colors);
527
    JSONObject solved      = object.getJSONObject("solved");
528
    parseSolved(solved);
529
    }
530

    
531
///////////////////////////////////////////////////////////////////////////////////////////////////
532

    
533
  private void parseVersion1Tutorial(JSONObject object) throws JSONException
534
    {
535
    mTutorialObject = object.getString("object");
536
    JSONArray tuts= object.getJSONArray("tutorials");
537

    
538
    int len = tuts.length();
539
    mTutorials = new String[len][4];
540

    
541
    for(int i=0; i<len; i++)
542
      {
543
      JSONObject tut = tuts.getJSONObject(i);
544
      mTutorials[i][0] = tut.getString("language");
545
      mTutorials[i][1] = tut.getString("link");
546
      mTutorials[i][2] = tut.getString("title");
547
      mTutorials[i][3] = tut.getString("author");
548
      }
549
    }
550

    
551
///////////////////////////////////////////////////////////////////////////////////////////////////
552

    
553
  private void parseVersion1Metadata(JSONObject object) throws JSONException
554
    {
555
    JSONObject metadata = object.getJSONObject("metadata");
556
    parseMetadata(metadata);
557
    }
558

    
559
///////////////////////////////////////////////////////////////////////////////////////////////////
560

    
561
  public void parseJsonFile(InputStream jsonStream)
562
    {
563
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
564

    
565
    try
566
      {
567
      StringBuilder contents = new StringBuilder();
568
      String tmp;
569
      while( (tmp = br.readLine()) != null) contents.append(tmp);
570
      br.close();
571
      jsonStream.close();
572

    
573
      JSONObject object = new JSONObject(contents.toString());
574
      int major = object.getInt("major");
575

    
576
      if( major==1 )
577
        {
578
        parseVersion1(object);
579
        }
580
      else
581
        {
582
        android.util.Log.e("readJsonFile", "Unknown version "+major);
583
        }
584
      }
585
    catch(IOException e)
586
      {
587
      android.util.Log.e("readJsonFile", "Error reading JSON file: "+e.toString());
588
      }
589
    catch( JSONException e )
590
      {
591
      android.util.Log.e("parseJsonFile", "Error parsing JSON file: "+e.toString());
592
      }
593
    }
594

    
595
///////////////////////////////////////////////////////////////////////////////////////////////////
596

    
597
  public void parseJsonFileMetadata(InputStream jsonStream)
598
    {
599
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
600

    
601
    try
602
      {
603
      StringBuilder contents = new StringBuilder();
604
      String tmp;
605
      while( (tmp = br.readLine()) != null) contents.append(tmp);
606
      br.close();
607
      jsonStream.close();
608

    
609
      JSONObject object = new JSONObject(contents.toString());
610
      int major = object.getInt("major");
611

    
612
      if( major==1 )
613
        {
614
        parseVersion1Metadata(object);
615
        }
616
      else
617
        {
618
        android.util.Log.e("readJsonFileQuick", "Unknown version "+major);
619
        }
620
      }
621
    catch(IOException e)
622
      {
623
      android.util.Log.e("readJsonFileQuick", "Error reading JSON file: "+e.toString());
624
      }
625
    catch( JSONException e )
626
      {
627
      android.util.Log.e("parseJsonFileQuick", "Error parsing JSON file: "+e.toString());
628
      }
629
    }
630

    
631
///////////////////////////////////////////////////////////////////////////////////////////////////
632

    
633
  public int readNumScrambles(Context context, String fileName)
634
    {
635
    File file = new File(context.getFilesDir(), fileName);
636
    InputStream stream;
637

    
638
    try
639
      {
640
      stream = new FileInputStream(file);
641
      BufferedReader br = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
642

    
643
      StringBuilder contents = new StringBuilder();
644
      String tmp;
645
      while( (tmp = br.readLine()) != null) contents.append(tmp);
646
      br.close();
647
      stream.close();
648

    
649
      JSONObject object = new JSONObject(contents.toString());
650
      int major = object.getInt("major");
651

    
652
      if( major==1 )
653
        {
654
        JSONObject metadata = object.getJSONObject("metadata");
655
        return metadata.getInt("scrambles");
656
        }
657
      else
658
        {
659
        android.util.Log.e("readNumScrambles", "Unknown version "+major);
660
        }
661
      }
662
    catch(FileNotFoundException ex)
663
      {
664
      android.util.Log.e("readNumScrambles", "file "+fileName+" not found: "+ex.getMessage());
665
      }
666
    catch(IOException e)
667
      {
668
      android.util.Log.e("readNumScrambles", "Error reading JSON file: "+e.toString());
669
      }
670
    catch( JSONException e )
671
      {
672
      android.util.Log.e("readNumScrambles", "Error parsing JSON file: "+e.toString());
673
      }
674

    
675
    return 0;
676
    }
677

    
678
///////////////////////////////////////////////////////////////////////////////////////////////////
679

    
680
  public void parseJsonTutorial(InputStream jsonStream)
681
    {
682
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
683

    
684
    try
685
      {
686
      StringBuilder contents = new StringBuilder();
687
      String tmp;
688
      while( (tmp = br.readLine()) != null) contents.append(tmp);
689
      br.close();
690
      jsonStream.close();
691

    
692
      JSONObject object = new JSONObject(contents.toString());
693
      int major = object.getInt("major");
694

    
695
      if( major==1 )
696
        {
697
        parseVersion1Tutorial(object);
698
        }
699
      else
700
        {
701
        android.util.Log.e("readJsonFile", "Unknown tutorial version "+major);
702
        }
703
      }
704
    catch(IOException e)
705
      {
706
      android.util.Log.e("readJsonFile", "Error reading JSON file: "+e.toString());
707
      }
708
    catch( JSONException e )
709
      {
710
      android.util.Log.e("parseJsonFile", "Error parsing JSON file: "+e.toString());
711
      }
712
    }
713

    
714
///////////////////////////////////////////////////////////////////////////////////////////////////
715

    
716
  public ScrambleState[] getScrambleStates()
717
    {
718
    return mStates;
719
    }
720

    
721
///////////////////////////////////////////////////////////////////////////////////////////////////
722

    
723
  public int[][] getSolvedQuats()
724
    {
725
    return mSolvedQuats;
726
    }
727

    
728
///////////////////////////////////////////////////////////////////////////////////////////////////
729

    
730
  public Static4D[] getQuats()
731
    {
732
    return mQuats;
733
    }
734

    
735
///////////////////////////////////////////////////////////////////////////////////////////////////
736

    
737
  public int getSolvedFunctionIndex()
738
    {
739
    return mSolvedFuncIndex;
740
    }
741

    
742
///////////////////////////////////////////////////////////////////////////////////////////////////
743

    
744
  public int getNumStickerTypes()
745
    {
746
    return mNumStickerTypes;
747
    }
748

    
749
///////////////////////////////////////////////////////////////////////////////////////////////////
750

    
751
  public float[][] getCuts()
752
    {
753
    return mCuts;
754
    }
755

    
756
///////////////////////////////////////////////////////////////////////////////////////////////////
757

    
758
  public boolean[][] getLayerRotatable()
759
    {
760
    return mLayerRotatable;
761
    }
762

    
763
///////////////////////////////////////////////////////////////////////////////////////////////////
764

    
765
  public int getMovementType()
766
    {
767
    return mMovementType;
768
    }
769

    
770
///////////////////////////////////////////////////////////////////////////////////////////////////
771

    
772
  public int getMovementSplit()
773
    {
774
    return mMovementSplit;
775
    }
776

    
777
///////////////////////////////////////////////////////////////////////////////////////////////////
778

    
779
  public int[][][] getEnabled()
780
    {
781
    return mEnabled;
782
    }
783

    
784
///////////////////////////////////////////////////////////////////////////////////////////////////
785

    
786
  public float[] getDist3D()
787
    {
788
    return mDist3D;
789
    }
790

    
791
///////////////////////////////////////////////////////////////////////////////////////////////////
792

    
793
  public int getNumCubitFaces()
794
    {
795
    return mNumCubitFaces;
796
    }
797

    
798
///////////////////////////////////////////////////////////////////////////////////////////////////
799

    
800
  public float[][] getCubitPositions()
801
    {
802
    return mPositions;
803
    }
804

    
805
///////////////////////////////////////////////////////////////////////////////////////////////////
806

    
807
  public ObjectShape getObjectShape(int variant)
808
    {
809
    return mShapes[variant];
810
    }
811

    
812
///////////////////////////////////////////////////////////////////////////////////////////////////
813

    
814
  public ObjectFaceShape getObjectFaceShape(int variant)
815
    {
816
    return mFaceShapes[variant];
817
    }
818

    
819
///////////////////////////////////////////////////////////////////////////////////////////////////
820

    
821
  public Static4D getCubitQuats(int cubit)
822
    {
823
    return mCubitQuats[cubit];
824
    }
825

    
826
///////////////////////////////////////////////////////////////////////////////////////////////////
827

    
828
  public int getNumCubitVariants()
829
    {
830
    return mNumCubitVariants;
831
    }
832

    
833
///////////////////////////////////////////////////////////////////////////////////////////////////
834

    
835
  public int getCubitVariant(int cubit)
836
    {
837
    return mCubitVariant[cubit];
838
    }
839

    
840
///////////////////////////////////////////////////////////////////////////////////////////////////
841

    
842
  public int getVariantFaceColor(int variant, int face)
843
    {
844
    int[] colors = mVariantFaceColor[variant];
845
    return colors.length>face ? colors[face] : -1;
846
    }
847

    
848
///////////////////////////////////////////////////////////////////////////////////////////////////
849

    
850
  public int getCubitFaceFace(int cubit, int face)
851
    {
852
    return mCubitFaceColor[cubit][face];
853
    }
854

    
855
///////////////////////////////////////////////////////////////////////////////////////////////////
856

    
857
  public int getNumScrambles()
858
    {
859
    return mNumScrambles;
860
    }
861

    
862
///////////////////////////////////////////////////////////////////////////////////////////////////
863

    
864
  public ObjectSticker retSticker(int sticker)
865
    {
866
    return mObjectSticker[sticker];
867
    }
868

    
869
///////////////////////////////////////////////////////////////////////////////////////////////////
870

    
871
  public Static3D[] getRotationAxis()
872
    {
873
    return mAxis;
874
    }
875

    
876
///////////////////////////////////////////////////////////////////////////////////////////////////
877

    
878
  public int[] getBasicAngle()
879
    {
880
    return mBasicAngle;
881
    }
882

    
883
///////////////////////////////////////////////////////////////////////////////////////////////////
884

    
885
  public long getSignature()
886
    {
887
    return mSignature;
888
    }
889

    
890
///////////////////////////////////////////////////////////////////////////////////////////////////
891

    
892
  public String getObjectName()
893
    {
894
    return mLongName;
895
    }
896

    
897
///////////////////////////////////////////////////////////////////////////////////////////////////
898

    
899
  public String getShortName()
900
    {
901
    return mShortName;
902
    }
903

    
904
///////////////////////////////////////////////////////////////////////////////////////////////////
905

    
906
  public String getInventor()
907
    {
908
    return mInventor;
909
    }
910

    
911
///////////////////////////////////////////////////////////////////////////////////////////////////
912

    
913
  public int getYearOfInvention()
914
    {
915
    return mYearOfInvention;
916
    }
917

    
918
///////////////////////////////////////////////////////////////////////////////////////////////////
919

    
920
  public int getComplexity()
921
    {
922
    return mComplexity;
923
    }
924

    
925
///////////////////////////////////////////////////////////////////////////////////////////////////
926

    
927
  public int getNumFaces()
928
    {
929
    return mNumFaces;
930
    }
931

    
932
///////////////////////////////////////////////////////////////////////////////////////////////////
933

    
934
  public int getNumFaceColors()
935
    {
936
    return mNumFaceColors;
937
    }
938

    
939
///////////////////////////////////////////////////////////////////////////////////////////////////
940

    
941
  public int[] getNumLayers()
942
    {
943
    return mNumLayers;
944
    }
945

    
946
///////////////////////////////////////////////////////////////////////////////////////////////////
947

    
948
  public float getSize()
949
    {
950
    return mSize;
951
    }
952

    
953
///////////////////////////////////////////////////////////////////////////////////////////////////
954

    
955
  public int getScrambleType()
956
    {
957
    return mScrambleType;
958
    }
959

    
960
///////////////////////////////////////////////////////////////////////////////////////////////////
961

    
962
  public int getColor(int face)
963
    {
964
    return mColor[face];
965
    }
966

    
967
///////////////////////////////////////////////////////////////////////////////////////////////////
968

    
969
  public int getInternalColor()
970
    {
971
    return mInternalColor;
972
    }
973

    
974
///////////////////////////////////////////////////////////////////////////////////////////////////
975

    
976
  public boolean shouldResetTextureMaps()
977
    {
978
    return mResetMaps;
979
    }
980

    
981
///////////////////////////////////////////////////////////////////////////////////////////////////
982

    
983
  public String getTutorialObject()
984
    {
985
    return mTutorialObject;
986
    }
987

    
988
///////////////////////////////////////////////////////////////////////////////////////////////////
989

    
990
  public String[][] getTutorials()
991
    {
992
    return mTutorials;
993
    }
994

    
995
}
(1-1/2)