Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / json / JsonReader.java @ 1f656ca7

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.distorted.objectlib.helpers.ObjectSignature;
35
import org.distorted.objectlib.objects.TwistyBandagedCuboid;
36
import org.json.JSONArray;
37
import org.json.JSONException;
38
import org.json.JSONObject;
39

    
40
import org.distorted.library.type.Static3D;
41
import org.distorted.library.type.Static4D;
42

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

    
48
///////////////////////////////////////////////////////////////////////////////////////////////////
49

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

    
85
  private static JsonReader mThis;
86

    
87
///////////////////////////////////////////////////////////////////////////////////////////////////
88

    
89
  private JsonReader()
90
    {
91
    }
92

    
93
///////////////////////////////////////////////////////////////////////////////////////////////////
94

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

    
101
///////////////////////////////////////////////////////////////////////////////////////////////////
102

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

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

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

    
131
  private void parseMetadata2or3(JSONObject object) throws JSONException
132
    {
133
    mLongName        = object.getString("longname");
134
    mShortName       = object.getString("shortname");
135
    mInventor        = object.getString("inventor");
136
    mYearOfInvention = object.getInt("year");
137
    mComplexity      = object.getInt("complexity");
138
    mSize            = (float)object.getDouble("size");
139
    mNumScrambles    = object.getInt("scrambles");
140
    mResetMaps       = object.getBoolean("resetmaps");
141
    mNumFaces        = object.getInt("num_faces");
142

    
143
    try
144
      {
145
      long signature1 = object.getLong("signature1");
146
      long signature2 = object.getLong("signature2");
147
      long signature3 = object.getLong("signature3");
148

    
149
      switch( TwistyBandagedCuboid.getType(mShortName) )
150
        {
151
        case 0: mSignature = new ObjectSignature(signature1,signature2,signature3); break;
152
        case 1: mSignature = new ObjectSignature(mShortName,signature1,signature2,signature3); break;
153
        case 2: mSignature = new ObjectSignature("333",signature1,signature2,signature3); break;
154
        }
155
      }
156
    catch(JSONException ex)
157
      {
158
      long signature = object.getLong("signature");
159
      mSignature = new ObjectSignature(signature);
160
      }
161
    }
162

    
163
///////////////////////////////////////////////////////////////////////////////////////////////////
164

    
165
  private void parseCubits(JSONArray object) throws JSONException
166
    {
167
    int numCubits = object.length();
168

    
169
    mCubitQuats     = new Static4D[numCubits];
170
    mCubitVariant   = new int[numCubits];
171
    mPositions      = new float[numCubits][];
172
    mCubitFaceColor = new int[numCubits][];
173

    
174
    for(int i=0; i<numCubits; i++)
175
      {
176
      JSONObject jsonCubit = object.getJSONObject(i);
177

    
178
      float qx = (float)jsonCubit.getDouble("qx");
179
      float qy = (float)jsonCubit.getDouble("qy");
180
      float qz = (float)jsonCubit.getDouble("qz");
181
      float qw = (float)jsonCubit.getDouble("qw");
182

    
183
      mCubitQuats[i] = new Static4D(qx,qy,qz,qw);
184
      mCubitVariant[i] = jsonCubit.getInt("variant");
185

    
186
      JSONArray jsonCenter = jsonCubit.getJSONArray("centers");
187
      int numCenter = jsonCenter.length();
188
      mPositions[i] = new float[numCenter];
189
      for(int j=0; j<numCenter; j++) mPositions[i][j] = (float)jsonCenter.getDouble(j);
190

    
191
      JSONArray jsonColor  = jsonCubit.getJSONArray("colors");
192
      int numColor = jsonColor.length();
193
      mCubitFaceColor[i] = new int[numColor];
194
      for(int j=0; j<numColor; j++) mCubitFaceColor[i][j] = jsonColor.getInt(j);
195
      }
196
    }
197

    
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199

    
200
  private void parseShapes(JSONArray object) throws JSONException
201
    {
202
    mNumCubitVariants = object.length();
203
    mVariantFaceColor = new int[mNumCubitVariants][];
204
    mShapes     = new ObjectShape[mNumCubitVariants];
205
    mFaceShapes = new ObjectFaceShape[mNumCubitVariants];
206
    float[][][] verts     = new float[mNumCubitVariants][][];
207
    float[][][] bands     = new float[mNumCubitVariants][][];
208
    float[][][] corners   = new float[mNumCubitVariants][][];
209
    float[][][] centers   = new float[mNumCubitVariants][][];
210
    float[][] convexity   = new float[mNumCubitVariants][];
211
    int[][] cornerIndices = new int[mNumCubitVariants][];
212
    int[][] centerIndices = new int[mNumCubitVariants][];
213
    int[][] bandIndices   = new int[mNumCubitVariants][];
214
    int[][][] vertIndices = new int[mNumCubitVariants][][];
215

    
216
    mNumCubitFaces = -1;
217

    
218
    for(int i=0; i<mNumCubitVariants; i++)
219
      {
220
      JSONObject jsonShape = object.getJSONObject(i);
221

    
222
      ////// vertices /////////////////////////////////////////////////
223
      JSONArray jsonVertices= jsonShape.getJSONArray("vertices");
224
      int numVertices = jsonVertices.length();
225
      verts[i] = new float[numVertices][3];
226
      cornerIndices[i] = new int[numVertices];
227
      centerIndices[i] = new int[numVertices];
228

    
229
      for(int j=0; j<numVertices; j++)
230
        {
231
        JSONObject vert = jsonVertices.getJSONObject(j);
232
        verts[i][j][0] = (float)vert.getDouble("x");
233
        verts[i][j][1] = (float)vert.getDouble("y");
234
        verts[i][j][2] = (float)vert.getDouble("z");
235
        cornerIndices[i][j] = vert.getInt("cornerIndex");
236
        centerIndices[i][j] = vert.getInt("centerIndex");
237
        }
238

    
239
      ////// faces ////////////////////////////////////////////////////
240
      JSONArray jsonFaces= jsonShape.getJSONArray("faces");
241
      int numFaces = jsonFaces.length();
242
      mVariantFaceColor[i] = new int[numFaces];
243
      bandIndices[i] = new int[numFaces];
244
      vertIndices[i] = new int[numFaces][];
245

    
246
      if( mNumCubitFaces<numFaces ) mNumCubitFaces=numFaces;
247

    
248
      for(int j=0; j<numFaces; j++)
249
        {
250
        JSONObject jsonFace = jsonFaces.getJSONObject(j);
251
        mVariantFaceColor[i][j] = jsonFace.getInt("sticker");
252
        bandIndices[i][j] = jsonFace.getInt("bandIndex");
253
        JSONArray vertices = jsonFace.getJSONArray("vertexIndices");
254
        int numV = vertices.length();
255
        vertIndices[i][j] = new int[numV];
256
        for(int k=0; k<numV; k++) vertIndices[i][j][k] = vertices.getInt(k);
257
        }
258

    
259
      ////// bands ////////////////////////////////////////////////////
260
      JSONArray jsonBands= jsonShape.getJSONArray("bands");
261
      int numBands = jsonBands.length();
262
      bands[i] = new float[numBands][7];
263

    
264
      for(int j=0; j<numBands; j++)
265
        {
266
        JSONObject jsonBand = jsonBands.getJSONObject(j);
267

    
268
        bands[i][j][0] = (float)jsonBand.getDouble("height");
269
        bands[i][j][1] = (float)jsonBand.getDouble("angle");
270
        bands[i][j][2] = (float)jsonBand.getDouble("distanceToCenter");
271
        bands[i][j][3] = (float)jsonBand.getDouble("distanceToFlat");
272
        bands[i][j][4] = (float)jsonBand.getDouble("numOfBands");
273
        bands[i][j][5] = (float)jsonBand.getDouble("extraI");
274
        bands[i][j][6] = (float)jsonBand.getDouble("extraJ");
275
        }
276

    
277
      ////// cornerPush ///////////////////////////////////////////////
278
      JSONArray jsonCornerPush= jsonShape.optJSONArray("cornerPush");
279

    
280
      if( jsonCornerPush!=null )
281
        {
282
        int numCornerP = jsonCornerPush.length();
283
        corners[i] = new float[numCornerP][2];
284

    
285
        for(int j=0; j<numCornerP; j++)
286
          {
287
          JSONObject jsonC = jsonCornerPush.getJSONObject(j);
288
          corners[i][j][0] = (float)jsonC.getDouble("strength");
289
          corners[i][j][1] = (float)jsonC.getDouble("radius");
290
          }
291
        }
292

    
293
      ////// centerPush ///////////////////////////////////////////////
294
      JSONArray jsonCenterPush= jsonShape.optJSONArray("centerPush");
295

    
296
      if( jsonCenterPush!=null )
297
        {
298
        int numCenterP = jsonCenterPush.length();
299
        centers[i] = new float[numCenterP][3];
300

    
301
        for(int j=0; j<numCenterP; j++)
302
          {
303
          JSONObject jsonC = jsonCenterPush.getJSONObject(j);
304
          centers[i][j][0] = (float)jsonC.getDouble("x");
305
          centers[i][j][1] = (float)jsonC.getDouble("y");
306
          centers[i][j][2] = (float)jsonC.getDouble("z");
307
          }
308
        }
309

    
310
      ////// convexity ///////////////////////////////////////////////
311
      JSONObject jsonConvexity = jsonShape.optJSONObject("convexity");
312

    
313
      if( jsonConvexity!=null )
314
        {
315
        convexity[i] = new float[3];
316
        convexity[i][0] = (float)jsonConvexity.getDouble("x");
317
        convexity[i][1] = (float)jsonConvexity.getDouble("y");
318
        convexity[i][2] = (float)jsonConvexity.getDouble("z");
319
        }
320
      }
321

    
322
    for(int i=0; i<mNumCubitVariants; i++)
323
      {
324
      mShapes[i] = new ObjectShape(verts[i],vertIndices[i]);
325
      mFaceShapes[i] = new ObjectFaceShape(bands[i],bandIndices[i],corners[i],cornerIndices[i],centers[i],centerIndices[i],convexity[i] );
326
      }
327
    }
328

    
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

    
331
  private void parseStickers(JSONArray object) throws JSONException
332
    {
333
    mNumStickerTypes = object.length();
334
    mObjectSticker = new ObjectSticker[mNumStickerTypes];
335

    
336
    for(int i=0; i<mNumStickerTypes; i++)
337
      {
338
      JSONObject sticker = object.getJSONObject(i);
339
      float stroke = (float)sticker.getDouble("stroke");
340
      JSONArray vertices = sticker.getJSONArray("vertices");
341
      int numVertices = vertices.length();
342

    
343
      float[] coords     = new float[2*numVertices];
344
      float[] curvatures = new float[numVertices];
345
      float[] radii      = new float[numVertices];
346

    
347
      for(int j=0; j<numVertices; j++)
348
        {
349
        JSONObject vertex = vertices.getJSONObject(j);
350

    
351
        coords[2*j  ] = (float)vertex.getDouble("x");
352
        coords[2*j+1] = (float)vertex.getDouble("y");
353
        curvatures[j] = (float)vertex.getDouble("angle");
354
        radii[j]      = (float)vertex.getDouble("radius");
355
        }
356

    
357
      mObjectSticker[i] = new ObjectSticker(coords,curvatures,radii,stroke);
358
      }
359
    }
360

    
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362

    
363
  private void parseMesh(JSONObject object) throws JSONException
364
    {
365
    JSONArray cubits   = object.getJSONArray("cubits");
366
    parseCubits(cubits);
367
    JSONArray shapes   = object.getJSONArray("shapes");
368
    parseShapes(shapes);
369
    JSONArray stickers = object.getJSONArray("stickers");
370
    parseStickers(stickers);
371
    }
372

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

    
375
  private void parseAxis1(JSONArray object) throws JSONException
376
    {
377
    int numAxis = object.length();
378

    
379
    mBasicAngle     = new int[numAxis][];
380
    mAxis           = new Static3D[numAxis];
381
    mCuts           = new float[numAxis][];
382
    mLayerRotatable = new boolean[numAxis][];
383
    mNumLayers      = new int[numAxis];
384

    
385
    for(int i=0; i<numAxis; i++)
386
      {
387
      JSONObject jsonAx = object.getJSONObject(i);
388

    
389
      float x = (float)jsonAx.getDouble("x");
390
      float y = (float)jsonAx.getDouble("y");
391
      float z = (float)jsonAx.getDouble("z");
392

    
393
      mAxis[i] = new Static3D(x,y,z);
394

    
395
      JSONArray jsonCuts = jsonAx.getJSONArray("cuts");
396
      int numCuts = jsonCuts.length();
397
      mCuts[i] = new float[numCuts];
398
      for(int j=0; j<numCuts; j++) mCuts[i][j] = (float)jsonCuts.getDouble(j);
399

    
400
      JSONArray jsonRota = jsonAx.getJSONArray("rotatable");
401
      int numRota = jsonRota.length();
402
      mLayerRotatable[i] = new boolean[numRota];
403
      for(int j=0; j<numRota; j++) mLayerRotatable[i][j] = jsonRota.getBoolean(j);
404

    
405
      mBasicAngle[i] = new int[numRota];
406
      int basicAngle = jsonAx.getInt("basicAngle");
407
      for(int j=0; j<numRota; j++) mBasicAngle[i][j] = basicAngle;
408

    
409
      mNumLayers[i] = numRota;
410
      }
411
    }
412

    
413
///////////////////////////////////////////////////////////////////////////////////////////////////
414

    
415
  private void parseAxis2or3(JSONArray object) throws JSONException
416
    {
417
    int numAxis = object.length();
418

    
419
    mBasicAngle     = new int[numAxis][];
420
    mAxis           = new Static3D[numAxis];
421
    mCuts           = new float[numAxis][];
422
    mLayerRotatable = new boolean[numAxis][];
423
    mNumLayers      = new int[numAxis];
424

    
425
    for(int i=0; i<numAxis; i++)
426
      {
427
      JSONObject jsonAx = object.getJSONObject(i);
428

    
429
      float x = (float)jsonAx.getDouble("x");
430
      float y = (float)jsonAx.getDouble("y");
431
      float z = (float)jsonAx.getDouble("z");
432

    
433
      mAxis[i] = new Static3D(x,y,z);
434

    
435
      JSONArray jsonAngles = jsonAx.getJSONArray("basicAngles");
436
      int numAngles = jsonAngles.length();
437
      mBasicAngle[i] = new int[numAngles];
438
      for(int j=0; j<numAngles; j++) mBasicAngle[i][j] = jsonAngles.getInt(j);
439

    
440
      JSONArray jsonCuts = jsonAx.getJSONArray("cuts");
441
      int numCuts = jsonCuts.length();
442
      mCuts[i] = new float[numCuts];
443
      for(int j=0; j<numCuts; j++) mCuts[i][j] = (float)jsonCuts.getDouble(j);
444

    
445
      JSONArray jsonRota = jsonAx.getJSONArray("rotatable");
446
      int numRota = jsonRota.length();
447
      mLayerRotatable[i] = new boolean[numRota];
448
      for(int j=0; j<numRota; j++) mLayerRotatable[i][j] = jsonRota.getBoolean(j);
449

    
450
      mNumLayers[i] = numRota;
451
      }
452
    }
453

    
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455

    
456
  private void parseQuats(JSONArray object) throws JSONException
457
    {
458
    int numQuats = object.length();
459
    mQuats = new Static4D[numQuats];
460

    
461
    for(int i=0; i<numQuats; i++)
462
      {
463
      JSONObject jsonQuat = object.getJSONObject(i);
464

    
465
      float x = (float)jsonQuat.getDouble("x");
466
      float y = (float)jsonQuat.getDouble("y");
467
      float z = (float)jsonQuat.getDouble("z");
468
      float w = (float)jsonQuat.getDouble("w");
469

    
470
      mQuats[i] = new Static4D(x,y,z,w);
471
      }
472
    }
473

    
474
///////////////////////////////////////////////////////////////////////////////////////////////////
475

    
476
  private void parseScrambling(JSONObject object) throws JSONException
477
    {
478
    mScrambleType = object.getInt("scrambleType");
479

    
480
    if( mScrambleType==0 )
481
      {
482
      JSONArray jsonStates = object.getJSONArray("scrambleStates");
483
      int numStates = jsonStates.length();
484
      mStates = new ScrambleState[numStates];
485

    
486
      for(int i=0; i<numStates; i++)
487
        {
488
        JSONArray jsonState = jsonStates.getJSONArray(i);
489
        int numAxis = jsonState.length();
490
        int[][] scramblingData = new int[numAxis][];
491

    
492
        for(int j=0; j<numAxis; j++)
493
          {
494
          JSONArray jsonData = jsonState.getJSONArray(j);
495
          int numData = jsonData.length();
496
          scramblingData[j] = new int[numData];
497
          for(int k=0; k<numData; k++) scramblingData[j][k] = jsonData.getInt(k);
498
          }
499

    
500
        mStates[i] = new ScrambleState(scramblingData);
501
        }
502
      }
503
    }
504

    
505
///////////////////////////////////////////////////////////////////////////////////////////////////
506

    
507
  private void parseTouchcontrol(JSONObject object) throws JSONException
508
    {
509
    mMovementType = object.getInt("movementType");
510
    mMovementSplit= object.getInt("movementSplit");
511

    
512
    try
513
      {
514
      JSONArray jsonEnabled = object.getJSONArray("enabledAxis");
515
      int numFace = jsonEnabled.length();
516

    
517
      mEnabled = new int[numFace][][];
518

    
519
      for(int i=0; i<numFace; i++)
520
        {
521
        JSONArray jsonSection = jsonEnabled.getJSONArray(i);
522
        int numSection = jsonSection.length();
523
        mEnabled[i] = new int[numSection][];
524

    
525
        for(int j=0; j<numSection; j++)
526
          {
527
          JSONArray jsonAx = jsonSection.getJSONArray(j);
528
          int numAxis = jsonAx.length();
529
          mEnabled[i][j] = new int[numAxis];
530
          for(int k=0; k<numAxis; k++) mEnabled[i][j][k] = jsonAx.getInt(k);
531
          }
532
        }
533
      }
534
    catch( JSONException ex )
535
      {
536
      // ignore, the object does not have to have 'enabledAxis' defined at all.
537
      }
538

    
539
    try
540
      {
541
      JSONArray jsonDist = object.getJSONArray("dist3D");
542
      int num = jsonDist.length();
543
      mDist3D = new float[num];
544
      for(int j=0; j<num; j++) mDist3D[j] = (float)jsonDist.getDouble(j);
545
      }
546
    catch( JSONException ex )
547
      {
548
      // ignore, the object does not have a 'dist3D' which is possible.
549
      }
550
    }
551

    
552
///////////////////////////////////////////////////////////////////////////////////////////////////
553

    
554
  private void parseColors(JSONArray object) throws JSONException
555
    {
556
    mNumFaceColors = object.length()-1;
557

    
558
    mColor = new int[mNumFaceColors];
559
    for(int i=0; i<mNumFaceColors; i++) mColor[i] = object.getInt(i);
560

    
561
    mInternalColor = object.getInt(mNumFaceColors);
562
    }
563

    
564
///////////////////////////////////////////////////////////////////////////////////////////////////
565

    
566
  private void parseSolved(JSONObject solved) throws JSONException
567
    {
568
    mSolvedFuncIndex = solved.getInt("functionIndex");
569

    
570
    try
571
      {
572
      JSONArray groupArray= solved.getJSONArray("groups");
573
      int numGroups = groupArray.length();
574
      mSolvedQuats  = new int[numGroups][];
575

    
576
      for(int i=0; i<numGroups; i++)
577
        {
578
        JSONArray groupElements = groupArray.getJSONArray(i);
579
        int groupSize = groupElements.length();
580
        mSolvedQuats[i] = new int[groupSize];
581
        for(int j=0; j<groupSize; j++) mSolvedQuats[i][j] = groupElements.getInt(j);
582
        }
583
      }
584
    catch( JSONException ex )
585
      {
586
      // ignore, the object does not have to have an array of solved groups.
587
      }
588
    }
589

    
590
///////////////////////////////////////////////////////////////////////////////////////////////////
591

    
592
  private void parseVersion1(JSONObject object) throws JSONException
593
    {
594
    JSONObject metadata    = object.getJSONObject("metadata");
595
    parseMetadata1(metadata);
596
    JSONObject mesh        = object.getJSONObject("mesh");
597
    parseMesh(mesh);
598
    JSONArray axis         = object.getJSONArray("axis");
599
    parseAxis1(axis);
600
    JSONArray quats        = object.getJSONArray("quats");
601
    parseQuats(quats);
602
    JSONObject scrambling  = object.getJSONObject("scrambling");
603
    parseScrambling(scrambling);
604
    JSONObject touchcontrol= object.getJSONObject("touchcontrol");
605
    parseTouchcontrol(touchcontrol);
606
    JSONArray colors       = object.getJSONArray("colors");
607
    parseColors(colors);
608
    JSONObject solved      = object.getJSONObject("solved");
609
    parseSolved(solved);
610
    }
611

    
612
///////////////////////////////////////////////////////////////////////////////////////////////////
613

    
614
  private void parseVersion2or3(JSONObject object) throws JSONException
615
    {
616
    JSONObject metadata    = object.getJSONObject("metadata");
617
    parseMetadata2or3(metadata);
618
    JSONObject mesh        = object.getJSONObject("mesh");
619
    parseMesh(mesh);
620
    JSONArray axis         = object.getJSONArray("axis");
621
    parseAxis2or3(axis);
622
    JSONArray quats        = object.getJSONArray("quats");
623
    parseQuats(quats);
624
    JSONObject scrambling  = object.getJSONObject("scrambling");
625
    parseScrambling(scrambling);
626
    JSONObject touchcontrol= object.getJSONObject("touchcontrol");
627
    parseTouchcontrol(touchcontrol);
628
    JSONArray colors       = object.getJSONArray("colors");
629
    parseColors(colors);
630
    JSONObject solved      = object.getJSONObject("solved");
631
    parseSolved(solved);
632
    }
633

    
634
///////////////////////////////////////////////////////////////////////////////////////////////////
635

    
636
  private void parseVersion1Tutorial(JSONObject object) throws JSONException
637
    {
638
    mTutorialObject = object.getString("object");
639
    JSONArray tuts= object.getJSONArray("tutorials");
640

    
641
    int len = tuts.length();
642
    mTutorials = new String[len][4];
643

    
644
    for(int i=0; i<len; i++)
645
      {
646
      JSONObject tut = tuts.getJSONObject(i);
647
      mTutorials[i][0] = tut.getString("language");
648
      mTutorials[i][1] = tut.getString("link");
649
      mTutorials[i][2] = tut.getString("title");
650
      mTutorials[i][3] = tut.getString("author");
651
      }
652
    }
653

    
654
///////////////////////////////////////////////////////////////////////////////////////////////////
655

    
656
  private void parseVersion1Metadata(JSONObject object) throws JSONException
657
    {
658
    JSONObject metadata = object.getJSONObject("metadata");
659
    parseMetadata1(metadata);
660
    }
661

    
662
///////////////////////////////////////////////////////////////////////////////////////////////////
663

    
664
  private void parseVersion2or3Metadata(JSONObject object) throws JSONException
665
    {
666
    JSONObject metadata = object.getJSONObject("metadata");
667
    parseMetadata2or3(metadata);
668
    }
669

    
670
///////////////////////////////////////////////////////////////////////////////////////////////////
671

    
672
  public void parseJsonFile(InputStream jsonStream)
673
    {
674
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
675

    
676
    try
677
      {
678
      StringBuilder contents = new StringBuilder();
679
      String tmp;
680
      while( (tmp = br.readLine()) != null) contents.append(tmp);
681
      br.close();
682
      jsonStream.close();
683

    
684
      JSONObject object = new JSONObject(contents.toString());
685
      int major = object.getInt("major");
686

    
687
      if( major==1 )
688
        {
689
        parseVersion1(object);
690
        }
691
      else if( major==2 || major==3 )
692
        {
693
        parseVersion2or3(object);
694
        }
695
      else
696
        {
697
        android.util.Log.e("readJsonFile", "Unknown version "+major);
698
        }
699
      }
700
    catch(IOException e)
701
      {
702
      android.util.Log.e("readJsonFile", "Error reading JSON file: "+e.toString());
703
      }
704
    catch( JSONException e )
705
      {
706
      android.util.Log.e("parseJsonFile", "Error parsing JSON file: "+e.toString());
707
      }
708
    }
709

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

    
712
  public void parseJsonFileMetadata(InputStream jsonStream)
713
    {
714
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
715

    
716
    try
717
      {
718
      StringBuilder contents = new StringBuilder();
719
      String tmp;
720
      while( (tmp = br.readLine()) != null) contents.append(tmp);
721
      br.close();
722
      jsonStream.close();
723

    
724
      JSONObject object = new JSONObject(contents.toString());
725
      int major = object.getInt("major");
726

    
727
      if( major==1 )
728
        {
729
        parseVersion1Metadata(object);
730
        }
731
      else if( major==2 || major==3 )
732
        {
733
        parseVersion2or3Metadata(object);
734
        }
735
      else
736
        {
737
        android.util.Log.e("readJsonFileQuick", "Unknown version "+major);
738
        }
739
      }
740
    catch(IOException e)
741
      {
742
      android.util.Log.e("readJsonFileQuick", "Error reading JSON file: "+e.toString());
743
      }
744
    catch( JSONException e )
745
      {
746
      android.util.Log.e("parseJsonFileQuick", "Error parsing JSON file: "+e.toString());
747
      }
748
    }
749

    
750
///////////////////////////////////////////////////////////////////////////////////////////////////
751

    
752
  public int readNumScrambles(Context context, String fileName)
753
    {
754
    File file = new File(context.getFilesDir(), fileName);
755
    InputStream stream;
756

    
757
    try
758
      {
759
      stream = new FileInputStream(file);
760
      BufferedReader br = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
761

    
762
      StringBuilder contents = new StringBuilder();
763
      String tmp;
764
      while( (tmp = br.readLine()) != null) contents.append(tmp);
765
      br.close();
766
      stream.close();
767

    
768
      JSONObject object = new JSONObject(contents.toString());
769
      int major = object.getInt("major");
770

    
771
      if( major==1 || major==2 || major==3 )
772
        {
773
        JSONObject metadata = object.getJSONObject("metadata");
774
        return metadata.getInt("scrambles");
775
        }
776
      else
777
        {
778
        android.util.Log.e("readNumScrambles", "Unknown version "+major);
779
        }
780
      }
781
    catch(FileNotFoundException ex)
782
      {
783
      android.util.Log.e("readNumScrambles", "file "+fileName+" not found: "+ex.getMessage());
784
      }
785
    catch(IOException e)
786
      {
787
      android.util.Log.e("readNumScrambles", "Error reading JSON file: "+e.toString());
788
      }
789
    catch( JSONException e )
790
      {
791
      android.util.Log.e("readNumScrambles", "Error parsing JSON file: "+e.toString());
792
      }
793

    
794
    return 0;
795
    }
796

    
797
///////////////////////////////////////////////////////////////////////////////////////////////////
798

    
799
  public void parseJsonTutorial(InputStream jsonStream)
800
    {
801
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
802

    
803
    try
804
      {
805
      StringBuilder contents = new StringBuilder();
806
      String tmp;
807
      while( (tmp = br.readLine()) != null) contents.append(tmp);
808
      br.close();
809
      jsonStream.close();
810

    
811
      JSONObject object = new JSONObject(contents.toString());
812
      int major = object.getInt("major");
813

    
814
      if( major==1 )
815
        {
816
        parseVersion1Tutorial(object);
817
        }
818
      else
819
        {
820
        android.util.Log.e("readJsonFile", "Unknown tutorial version "+major);
821
        }
822
      }
823
    catch(IOException e)
824
      {
825
      android.util.Log.e("readJsonFile", "Error reading JSON file: "+e.toString());
826
      }
827
    catch( JSONException e )
828
      {
829
      android.util.Log.e("parseJsonFile", "Error parsing JSON file: "+e.toString());
830
      }
831
    }
832

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

    
835
  public ScrambleState[] getScrambleStates()
836
    {
837
    return mStates;
838
    }
839

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

    
842
  public int[][] getSolvedQuats()
843
    {
844
    return mSolvedQuats;
845
    }
846

    
847
///////////////////////////////////////////////////////////////////////////////////////////////////
848

    
849
  public Static4D[] getQuats()
850
    {
851
    return mQuats;
852
    }
853

    
854
///////////////////////////////////////////////////////////////////////////////////////////////////
855

    
856
  public int getSolvedFunctionIndex()
857
    {
858
    return mSolvedFuncIndex;
859
    }
860

    
861
///////////////////////////////////////////////////////////////////////////////////////////////////
862

    
863
  public int getNumStickerTypes()
864
    {
865
    return mNumStickerTypes;
866
    }
867

    
868
///////////////////////////////////////////////////////////////////////////////////////////////////
869

    
870
  public float[][] getCuts()
871
    {
872
    return mCuts;
873
    }
874

    
875
///////////////////////////////////////////////////////////////////////////////////////////////////
876

    
877
  public boolean[][] getLayerRotatable()
878
    {
879
    return mLayerRotatable;
880
    }
881

    
882
///////////////////////////////////////////////////////////////////////////////////////////////////
883

    
884
  public int getMovementType()
885
    {
886
    return mMovementType;
887
    }
888

    
889
///////////////////////////////////////////////////////////////////////////////////////////////////
890

    
891
  public int getMovementSplit()
892
    {
893
    return mMovementSplit;
894
    }
895

    
896
///////////////////////////////////////////////////////////////////////////////////////////////////
897

    
898
  public int[][][] getEnabled()
899
    {
900
    return mEnabled;
901
    }
902

    
903
///////////////////////////////////////////////////////////////////////////////////////////////////
904

    
905
  public float[] getDist3D()
906
    {
907
    return mDist3D;
908
    }
909

    
910
///////////////////////////////////////////////////////////////////////////////////////////////////
911

    
912
  public int getNumCubitFaces()
913
    {
914
    return mNumCubitFaces;
915
    }
916

    
917
///////////////////////////////////////////////////////////////////////////////////////////////////
918

    
919
  public float[][] getCubitPositions()
920
    {
921
    return mPositions;
922
    }
923

    
924
///////////////////////////////////////////////////////////////////////////////////////////////////
925

    
926
  public ObjectShape getObjectShape(int variant)
927
    {
928
    return mShapes[variant];
929
    }
930

    
931
///////////////////////////////////////////////////////////////////////////////////////////////////
932

    
933
  public ObjectFaceShape getObjectFaceShape(int variant)
934
    {
935
    return mFaceShapes[variant];
936
    }
937

    
938
///////////////////////////////////////////////////////////////////////////////////////////////////
939

    
940
  public Static4D getCubitQuats(int cubit)
941
    {
942
    return mCubitQuats[cubit];
943
    }
944

    
945
///////////////////////////////////////////////////////////////////////////////////////////////////
946

    
947
  public int getNumCubitVariants()
948
    {
949
    return mNumCubitVariants;
950
    }
951

    
952
///////////////////////////////////////////////////////////////////////////////////////////////////
953

    
954
  public int getCubitVariant(int cubit)
955
    {
956
    return mCubitVariant[cubit];
957
    }
958

    
959
///////////////////////////////////////////////////////////////////////////////////////////////////
960

    
961
  public int getVariantFaceColor(int variant, int face)
962
    {
963
    int[] colors = mVariantFaceColor[variant];
964
    return colors.length>face ? colors[face] : -1;
965
    }
966

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

    
969
  public int getCubitFaceFace(int cubit, int face)
970
    {
971
    return mCubitFaceColor[cubit][face];
972
    }
973

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

    
976
  public int getNumScrambles()
977
    {
978
    return mNumScrambles;
979
    }
980

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

    
983
  public ObjectSticker retSticker(int sticker)
984
    {
985
    return mObjectSticker[sticker];
986
    }
987

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

    
990
  public Static3D[] getRotationAxis()
991
    {
992
    return mAxis;
993
    }
994

    
995
///////////////////////////////////////////////////////////////////////////////////////////////////
996

    
997
  public int[][] getBasicAngle()
998
    {
999
    return mBasicAngle;
1000
    }
1001

    
1002
///////////////////////////////////////////////////////////////////////////////////////////////////
1003

    
1004
  public ObjectSignature getSignature()
1005
    {
1006
    return mSignature;
1007
    }
1008

    
1009
///////////////////////////////////////////////////////////////////////////////////////////////////
1010

    
1011
  public String getObjectName()
1012
    {
1013
    return mLongName;
1014
    }
1015

    
1016
///////////////////////////////////////////////////////////////////////////////////////////////////
1017

    
1018
  public String getShortName()
1019
    {
1020
    return mShortName;
1021
    }
1022

    
1023
///////////////////////////////////////////////////////////////////////////////////////////////////
1024

    
1025
  public String getInventor()
1026
    {
1027
    return mInventor;
1028
    }
1029

    
1030
///////////////////////////////////////////////////////////////////////////////////////////////////
1031

    
1032
  public int getYearOfInvention()
1033
    {
1034
    return mYearOfInvention;
1035
    }
1036

    
1037
///////////////////////////////////////////////////////////////////////////////////////////////////
1038

    
1039
  public int getComplexity()
1040
    {
1041
    return mComplexity;
1042
    }
1043

    
1044
///////////////////////////////////////////////////////////////////////////////////////////////////
1045

    
1046
  public int getNumFaces()
1047
    {
1048
    return mNumFaces;
1049
    }
1050

    
1051
///////////////////////////////////////////////////////////////////////////////////////////////////
1052

    
1053
  public int getNumFaceColors()
1054
    {
1055
    return mNumFaceColors;
1056
    }
1057

    
1058
///////////////////////////////////////////////////////////////////////////////////////////////////
1059

    
1060
  public int[] getNumLayers()
1061
    {
1062
    return mNumLayers;
1063
    }
1064

    
1065
///////////////////////////////////////////////////////////////////////////////////////////////////
1066

    
1067
  public float getSize()
1068
    {
1069
    return mSize;
1070
    }
1071

    
1072
///////////////////////////////////////////////////////////////////////////////////////////////////
1073

    
1074
  public int getScrambleType()
1075
    {
1076
    return mScrambleType;
1077
    }
1078

    
1079
///////////////////////////////////////////////////////////////////////////////////////////////////
1080

    
1081
  public int getColor(int face)
1082
    {
1083
    return mColor[face];
1084
    }
1085

    
1086
///////////////////////////////////////////////////////////////////////////////////////////////////
1087

    
1088
  public int getInternalColor()
1089
    {
1090
    return mInternalColor;
1091
    }
1092

    
1093
///////////////////////////////////////////////////////////////////////////////////////////////////
1094

    
1095
  public boolean shouldResetTextureMaps()
1096
    {
1097
    return mResetMaps;
1098
    }
1099

    
1100
///////////////////////////////////////////////////////////////////////////////////////////////////
1101

    
1102
  public String getTutorialObject()
1103
    {
1104
    return mTutorialObject;
1105
    }
1106

    
1107
///////////////////////////////////////////////////////////////////////////////////////////////////
1108

    
1109
  public String[][] getTutorials()
1110
    {
1111
    return mTutorials;
1112
    }
1113

    
1114
}
(1-1/2)