Project

General

Profile

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

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

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 parseAxis1(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
      float x = (float)jsonAx.getDouble("x");
352
      float y = (float)jsonAx.getDouble("y");
353
      float z = (float)jsonAx.getDouble("z");
354

    
355
      mAxis[i] = new Static3D(x,y,z);
356

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

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

    
367
      mBasicAngle[i] = new int[numRota];
368
      int basicAngle = jsonAx.getInt("basicAngle");
369
      for(int j=0; j<numRota; j++) mBasicAngle[i][j] = basicAngle;
370

    
371
      mNumLayers[i] = numRota;
372
      }
373
    }
374

    
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376

    
377
  private void parseAxis2(JSONArray object) throws JSONException
378
    {
379
    int numAxis = object.length();
380

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

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

    
391
      float x = (float)jsonAx.getDouble("x");
392
      float y = (float)jsonAx.getDouble("y");
393
      float z = (float)jsonAx.getDouble("z");
394

    
395
      mAxis[i] = new Static3D(x,y,z);
396

    
397
      JSONArray jsonAngles = jsonAx.getJSONArray("basicAngles");
398
      int numAngles = jsonAngles.length();
399
      mBasicAngle[i] = new int[numAngles];
400
      for(int j=0; j<numAngles; j++) mBasicAngle[i][j] = jsonAngles.getInt(j);
401

    
402
      JSONArray jsonCuts = jsonAx.getJSONArray("cuts");
403
      int numCuts = jsonCuts.length();
404
      mCuts[i] = new float[numCuts];
405
      for(int j=0; j<numCuts; j++) mCuts[i][j] = (float)jsonCuts.getDouble(j);
406

    
407
      JSONArray jsonRota = jsonAx.getJSONArray("rotatable");
408
      int numRota = jsonRota.length();
409
      mLayerRotatable[i] = new boolean[numRota];
410
      for(int j=0; j<numRota; j++) mLayerRotatable[i][j] = jsonRota.getBoolean(j);
411

    
412
      mNumLayers[i] = numRota;
413
      }
414
    }
415

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

    
418
  private void parseQuats(JSONArray object) throws JSONException
419
    {
420
    int numQuats = object.length();
421
    mQuats = new Static4D[numQuats];
422

    
423
    for(int i=0; i<numQuats; i++)
424
      {
425
      JSONObject jsonQuat = object.getJSONObject(i);
426

    
427
      float x = (float)jsonQuat.getDouble("x");
428
      float y = (float)jsonQuat.getDouble("y");
429
      float z = (float)jsonQuat.getDouble("z");
430
      float w = (float)jsonQuat.getDouble("w");
431

    
432
      mQuats[i] = new Static4D(x,y,z,w);
433
      }
434
    }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

    
438
  private void parseScrambling(JSONObject object) throws JSONException
439
    {
440
    mScrambleType = object.getInt("scrambleType");
441

    
442
    if( mScrambleType==0 )
443
      {
444
      JSONArray jsonStates = object.getJSONArray("scrambleStates");
445
      int numStates = jsonStates.length();
446
      mStates = new ScrambleState[numStates];
447

    
448
      for(int i=0; i<numStates; i++)
449
        {
450
        JSONArray jsonState = jsonStates.getJSONArray(i);
451
        int numAxis = jsonState.length();
452
        int[][] scramblingData = new int[numAxis][];
453

    
454
        for(int j=0; j<numAxis; j++)
455
          {
456
          JSONArray jsonData = jsonState.getJSONArray(j);
457
          int numData = jsonData.length();
458
          scramblingData[j] = new int[numData];
459
          for(int k=0; k<numData; k++) scramblingData[j][k] = jsonData.getInt(k);
460
          }
461

    
462
        mStates[i] = new ScrambleState(scramblingData);
463
        }
464
      }
465
    }
466

    
467
///////////////////////////////////////////////////////////////////////////////////////////////////
468

    
469
  private void parseTouchcontrol(JSONObject object) throws JSONException
470
    {
471
    mMovementType = object.getInt("movementType");
472
    mMovementSplit= object.getInt("movementSplit");
473

    
474
    try
475
      {
476
      JSONArray jsonEnabled = object.getJSONArray("enabledAxis");
477
      int numFace = jsonEnabled.length();
478

    
479
      mEnabled = new int[numFace][][];
480

    
481
      for(int i=0; i<numFace; i++)
482
        {
483
        JSONArray jsonSection = jsonEnabled.getJSONArray(i);
484
        int numSection = jsonSection.length();
485
        mEnabled[i] = new int[numSection][];
486

    
487
        for(int j=0; j<numSection; j++)
488
          {
489
          JSONArray jsonAx = jsonSection.getJSONArray(j);
490
          int numAxis = jsonAx.length();
491
          mEnabled[i][j] = new int[numAxis];
492
          for(int k=0; k<numAxis; k++) mEnabled[i][j][k] = jsonAx.getInt(k);
493
          }
494
        }
495
      }
496
    catch( JSONException ex )
497
      {
498
      // ignore, the object does not have to have 'enabledAxis' defined at all.
499
      }
500

    
501
    try
502
      {
503
      JSONArray jsonDist = object.getJSONArray("dist3D");
504
      int num = jsonDist.length();
505
      mDist3D = new float[num];
506
      for(int j=0; j<num; j++) mDist3D[j] = (float)jsonDist.getDouble(j);
507
      }
508
    catch( JSONException ex )
509
      {
510
      // ignore, the object does not have a 'dist3D' which is possible.
511
      }
512
    }
513

    
514
///////////////////////////////////////////////////////////////////////////////////////////////////
515

    
516
  private void parseColors(JSONArray object) throws JSONException
517
    {
518
    mNumFaceColors = object.length()-1;
519

    
520
    mColor = new int[mNumFaceColors];
521
    for(int i=0; i<mNumFaceColors; i++) mColor[i] = object.getInt(i);
522

    
523
    mInternalColor = object.getInt(mNumFaceColors);
524
    }
525

    
526
///////////////////////////////////////////////////////////////////////////////////////////////////
527

    
528
  private void parseSolved(JSONObject solved) throws JSONException
529
    {
530
    mSolvedFuncIndex = solved.getInt("functionIndex");
531

    
532
    try
533
      {
534
      JSONArray groupArray= solved.getJSONArray("groups");
535
      int numGroups = groupArray.length();
536
      mSolvedQuats  = new int[numGroups][];
537

    
538
      for(int i=0; i<numGroups; i++)
539
        {
540
        JSONArray groupElements = groupArray.getJSONArray(i);
541
        int groupSize = groupElements.length();
542
        mSolvedQuats[i] = new int[groupSize];
543
        for(int j=0; j<groupSize; j++) mSolvedQuats[i][j] = groupElements.getInt(j);
544
        }
545
      }
546
    catch( JSONException ex )
547
      {
548
      // ignore, the object does not have to have an array of solved groups.
549
      }
550
    }
551

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

    
554
  private void parseVersion1(JSONObject object) throws JSONException
555
    {
556
    JSONObject metadata    = object.getJSONObject("metadata");
557
    parseMetadata(metadata);
558
    JSONObject mesh        = object.getJSONObject("mesh");
559
    parseMesh(mesh);
560
    JSONArray axis         = object.getJSONArray("axis");
561
    parseAxis1(axis);
562
    JSONArray quats        = object.getJSONArray("quats");
563
    parseQuats(quats);
564
    JSONObject scrambling  = object.getJSONObject("scrambling");
565
    parseScrambling(scrambling);
566
    JSONObject touchcontrol= object.getJSONObject("touchcontrol");
567
    parseTouchcontrol(touchcontrol);
568
    JSONArray colors       = object.getJSONArray("colors");
569
    parseColors(colors);
570
    JSONObject solved      = object.getJSONObject("solved");
571
    parseSolved(solved);
572
    }
573

    
574
///////////////////////////////////////////////////////////////////////////////////////////////////
575

    
576
  private void parseVersion2(JSONObject object) throws JSONException
577
    {
578
    JSONObject metadata    = object.getJSONObject("metadata");
579
    parseMetadata(metadata);
580
    JSONObject mesh        = object.getJSONObject("mesh");
581
    parseMesh(mesh);
582
    JSONArray axis         = object.getJSONArray("axis");
583
    parseAxis2(axis);
584
    JSONArray quats        = object.getJSONArray("quats");
585
    parseQuats(quats);
586
    JSONObject scrambling  = object.getJSONObject("scrambling");
587
    parseScrambling(scrambling);
588
    JSONObject touchcontrol= object.getJSONObject("touchcontrol");
589
    parseTouchcontrol(touchcontrol);
590
    JSONArray colors       = object.getJSONArray("colors");
591
    parseColors(colors);
592
    JSONObject solved      = object.getJSONObject("solved");
593
    parseSolved(solved);
594
    }
595

    
596
///////////////////////////////////////////////////////////////////////////////////////////////////
597

    
598
  private void parseVersion1Tutorial(JSONObject object) throws JSONException
599
    {
600
    mTutorialObject = object.getString("object");
601
    JSONArray tuts= object.getJSONArray("tutorials");
602

    
603
    int len = tuts.length();
604
    mTutorials = new String[len][4];
605

    
606
    for(int i=0; i<len; i++)
607
      {
608
      JSONObject tut = tuts.getJSONObject(i);
609
      mTutorials[i][0] = tut.getString("language");
610
      mTutorials[i][1] = tut.getString("link");
611
      mTutorials[i][2] = tut.getString("title");
612
      mTutorials[i][3] = tut.getString("author");
613
      }
614
    }
615

    
616
///////////////////////////////////////////////////////////////////////////////////////////////////
617

    
618
  private void parseVersion1or2Metadata(JSONObject object) throws JSONException
619
    {
620
    JSONObject metadata = object.getJSONObject("metadata");
621
    parseMetadata(metadata);
622
    }
623

    
624
///////////////////////////////////////////////////////////////////////////////////////////////////
625

    
626
  public void parseJsonFile(InputStream jsonStream)
627
    {
628
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
629

    
630
    try
631
      {
632
      StringBuilder contents = new StringBuilder();
633
      String tmp;
634
      while( (tmp = br.readLine()) != null) contents.append(tmp);
635
      br.close();
636
      jsonStream.close();
637

    
638
      JSONObject object = new JSONObject(contents.toString());
639
      int major = object.getInt("major");
640

    
641
      if( major==1 )
642
        {
643
        parseVersion1(object);
644
        }
645
      else if( major==2 )
646
        {
647
        parseVersion2(object);
648
        }
649
      else
650
        {
651
        android.util.Log.e("readJsonFile", "Unknown version "+major);
652
        }
653
      }
654
    catch(IOException e)
655
      {
656
      android.util.Log.e("readJsonFile", "Error reading JSON file: "+e.toString());
657
      }
658
    catch( JSONException e )
659
      {
660
      android.util.Log.e("parseJsonFile", "Error parsing JSON file: "+e.toString());
661
      }
662
    }
663

    
664
///////////////////////////////////////////////////////////////////////////////////////////////////
665

    
666
  public void parseJsonFileMetadata(InputStream jsonStream)
667
    {
668
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
669

    
670
    try
671
      {
672
      StringBuilder contents = new StringBuilder();
673
      String tmp;
674
      while( (tmp = br.readLine()) != null) contents.append(tmp);
675
      br.close();
676
      jsonStream.close();
677

    
678
      JSONObject object = new JSONObject(contents.toString());
679
      int major = object.getInt("major");
680

    
681
      if( major==1 || major==2 )
682
        {
683
        parseVersion1or2Metadata(object);
684
        }
685
      else
686
        {
687
        android.util.Log.e("readJsonFileQuick", "Unknown version "+major);
688
        }
689
      }
690
    catch(IOException e)
691
      {
692
      android.util.Log.e("readJsonFileQuick", "Error reading JSON file: "+e.toString());
693
      }
694
    catch( JSONException e )
695
      {
696
      android.util.Log.e("parseJsonFileQuick", "Error parsing JSON file: "+e.toString());
697
      }
698
    }
699

    
700
///////////////////////////////////////////////////////////////////////////////////////////////////
701

    
702
  public int readNumScrambles(Context context, String fileName)
703
    {
704
    File file = new File(context.getFilesDir(), fileName);
705
    InputStream stream;
706

    
707
    try
708
      {
709
      stream = new FileInputStream(file);
710
      BufferedReader br = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
711

    
712
      StringBuilder contents = new StringBuilder();
713
      String tmp;
714
      while( (tmp = br.readLine()) != null) contents.append(tmp);
715
      br.close();
716
      stream.close();
717

    
718
      JSONObject object = new JSONObject(contents.toString());
719
      int major = object.getInt("major");
720

    
721
      if( major==1 || major==2 )
722
        {
723
        JSONObject metadata = object.getJSONObject("metadata");
724
        return metadata.getInt("scrambles");
725
        }
726
      else
727
        {
728
        android.util.Log.e("readNumScrambles", "Unknown version "+major);
729
        }
730
      }
731
    catch(FileNotFoundException ex)
732
      {
733
      android.util.Log.e("readNumScrambles", "file "+fileName+" not found: "+ex.getMessage());
734
      }
735
    catch(IOException e)
736
      {
737
      android.util.Log.e("readNumScrambles", "Error reading JSON file: "+e.toString());
738
      }
739
    catch( JSONException e )
740
      {
741
      android.util.Log.e("readNumScrambles", "Error parsing JSON file: "+e.toString());
742
      }
743

    
744
    return 0;
745
    }
746

    
747
///////////////////////////////////////////////////////////////////////////////////////////////////
748

    
749
  public void parseJsonTutorial(InputStream jsonStream)
750
    {
751
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
752

    
753
    try
754
      {
755
      StringBuilder contents = new StringBuilder();
756
      String tmp;
757
      while( (tmp = br.readLine()) != null) contents.append(tmp);
758
      br.close();
759
      jsonStream.close();
760

    
761
      JSONObject object = new JSONObject(contents.toString());
762
      int major = object.getInt("major");
763

    
764
      if( major==1 )
765
        {
766
        parseVersion1Tutorial(object);
767
        }
768
      else
769
        {
770
        android.util.Log.e("readJsonFile", "Unknown tutorial version "+major);
771
        }
772
      }
773
    catch(IOException e)
774
      {
775
      android.util.Log.e("readJsonFile", "Error reading JSON file: "+e.toString());
776
      }
777
    catch( JSONException e )
778
      {
779
      android.util.Log.e("parseJsonFile", "Error parsing JSON file: "+e.toString());
780
      }
781
    }
782

    
783
///////////////////////////////////////////////////////////////////////////////////////////////////
784

    
785
  public ScrambleState[] getScrambleStates()
786
    {
787
    return mStates;
788
    }
789

    
790
///////////////////////////////////////////////////////////////////////////////////////////////////
791

    
792
  public int[][] getSolvedQuats()
793
    {
794
    return mSolvedQuats;
795
    }
796

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

    
799
  public Static4D[] getQuats()
800
    {
801
    return mQuats;
802
    }
803

    
804
///////////////////////////////////////////////////////////////////////////////////////////////////
805

    
806
  public int getSolvedFunctionIndex()
807
    {
808
    return mSolvedFuncIndex;
809
    }
810

    
811
///////////////////////////////////////////////////////////////////////////////////////////////////
812

    
813
  public int getNumStickerTypes()
814
    {
815
    return mNumStickerTypes;
816
    }
817

    
818
///////////////////////////////////////////////////////////////////////////////////////////////////
819

    
820
  public float[][] getCuts()
821
    {
822
    return mCuts;
823
    }
824

    
825
///////////////////////////////////////////////////////////////////////////////////////////////////
826

    
827
  public boolean[][] getLayerRotatable()
828
    {
829
    return mLayerRotatable;
830
    }
831

    
832
///////////////////////////////////////////////////////////////////////////////////////////////////
833

    
834
  public int getMovementType()
835
    {
836
    return mMovementType;
837
    }
838

    
839
///////////////////////////////////////////////////////////////////////////////////////////////////
840

    
841
  public int getMovementSplit()
842
    {
843
    return mMovementSplit;
844
    }
845

    
846
///////////////////////////////////////////////////////////////////////////////////////////////////
847

    
848
  public int[][][] getEnabled()
849
    {
850
    return mEnabled;
851
    }
852

    
853
///////////////////////////////////////////////////////////////////////////////////////////////////
854

    
855
  public float[] getDist3D()
856
    {
857
    return mDist3D;
858
    }
859

    
860
///////////////////////////////////////////////////////////////////////////////////////////////////
861

    
862
  public int getNumCubitFaces()
863
    {
864
    return mNumCubitFaces;
865
    }
866

    
867
///////////////////////////////////////////////////////////////////////////////////////////////////
868

    
869
  public float[][] getCubitPositions()
870
    {
871
    return mPositions;
872
    }
873

    
874
///////////////////////////////////////////////////////////////////////////////////////////////////
875

    
876
  public ObjectShape getObjectShape(int variant)
877
    {
878
    return mShapes[variant];
879
    }
880

    
881
///////////////////////////////////////////////////////////////////////////////////////////////////
882

    
883
  public ObjectFaceShape getObjectFaceShape(int variant)
884
    {
885
    return mFaceShapes[variant];
886
    }
887

    
888
///////////////////////////////////////////////////////////////////////////////////////////////////
889

    
890
  public Static4D getCubitQuats(int cubit)
891
    {
892
    return mCubitQuats[cubit];
893
    }
894

    
895
///////////////////////////////////////////////////////////////////////////////////////////////////
896

    
897
  public int getNumCubitVariants()
898
    {
899
    return mNumCubitVariants;
900
    }
901

    
902
///////////////////////////////////////////////////////////////////////////////////////////////////
903

    
904
  public int getCubitVariant(int cubit)
905
    {
906
    return mCubitVariant[cubit];
907
    }
908

    
909
///////////////////////////////////////////////////////////////////////////////////////////////////
910

    
911
  public int getVariantFaceColor(int variant, int face)
912
    {
913
    int[] colors = mVariantFaceColor[variant];
914
    return colors.length>face ? colors[face] : -1;
915
    }
916

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

    
919
  public int getCubitFaceFace(int cubit, int face)
920
    {
921
    return mCubitFaceColor[cubit][face];
922
    }
923

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

    
926
  public int getNumScrambles()
927
    {
928
    return mNumScrambles;
929
    }
930

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

    
933
  public ObjectSticker retSticker(int sticker)
934
    {
935
    return mObjectSticker[sticker];
936
    }
937

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

    
940
  public Static3D[] getRotationAxis()
941
    {
942
    return mAxis;
943
    }
944

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

    
947
  public int[][] getBasicAngle()
948
    {
949
    return mBasicAngle;
950
    }
951

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

    
954
  public long getSignature()
955
    {
956
    return mSignature;
957
    }
958

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

    
961
  public String getObjectName()
962
    {
963
    return mLongName;
964
    }
965

    
966
///////////////////////////////////////////////////////////////////////////////////////////////////
967

    
968
  public String getShortName()
969
    {
970
    return mShortName;
971
    }
972

    
973
///////////////////////////////////////////////////////////////////////////////////////////////////
974

    
975
  public String getInventor()
976
    {
977
    return mInventor;
978
    }
979

    
980
///////////////////////////////////////////////////////////////////////////////////////////////////
981

    
982
  public int getYearOfInvention()
983
    {
984
    return mYearOfInvention;
985
    }
986

    
987
///////////////////////////////////////////////////////////////////////////////////////////////////
988

    
989
  public int getComplexity()
990
    {
991
    return mComplexity;
992
    }
993

    
994
///////////////////////////////////////////////////////////////////////////////////////////////////
995

    
996
  public int getNumFaces()
997
    {
998
    return mNumFaces;
999
    }
1000

    
1001
///////////////////////////////////////////////////////////////////////////////////////////////////
1002

    
1003
  public int getNumFaceColors()
1004
    {
1005
    return mNumFaceColors;
1006
    }
1007

    
1008
///////////////////////////////////////////////////////////////////////////////////////////////////
1009

    
1010
  public int[] getNumLayers()
1011
    {
1012
    return mNumLayers;
1013
    }
1014

    
1015
///////////////////////////////////////////////////////////////////////////////////////////////////
1016

    
1017
  public float getSize()
1018
    {
1019
    return mSize;
1020
    }
1021

    
1022
///////////////////////////////////////////////////////////////////////////////////////////////////
1023

    
1024
  public int getScrambleType()
1025
    {
1026
    return mScrambleType;
1027
    }
1028

    
1029
///////////////////////////////////////////////////////////////////////////////////////////////////
1030

    
1031
  public int getColor(int face)
1032
    {
1033
    return mColor[face];
1034
    }
1035

    
1036
///////////////////////////////////////////////////////////////////////////////////////////////////
1037

    
1038
  public int getInternalColor()
1039
    {
1040
    return mInternalColor;
1041
    }
1042

    
1043
///////////////////////////////////////////////////////////////////////////////////////////////////
1044

    
1045
  public boolean shouldResetTextureMaps()
1046
    {
1047
    return mResetMaps;
1048
    }
1049

    
1050
///////////////////////////////////////////////////////////////////////////////////////////////////
1051

    
1052
  public String getTutorialObject()
1053
    {
1054
    return mTutorialObject;
1055
    }
1056

    
1057
///////////////////////////////////////////////////////////////////////////////////////////////////
1058

    
1059
  public String[][] getTutorials()
1060
    {
1061
    return mTutorials;
1062
    }
1063

    
1064
}
(1-1/2)