Project

General

Profile

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

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

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.objectlib.json;
11

    
12
import java.io.BufferedReader;
13
import java.io.File;
14
import java.io.FileInputStream;
15
import java.io.IOException;
16
import java.io.InputStream;
17
import java.io.InputStreamReader;
18
import java.nio.charset.StandardCharsets;
19

    
20
import android.content.Context;
21

    
22
import org.distorted.objectlib.helpers.ObjectFaceShape;
23
import org.distorted.objectlib.helpers.ObjectSignature;
24
import org.distorted.objectlib.helpers.ObjectStickerOverride;
25
import org.distorted.objectlib.helpers.ObjectVertexEffects;
26
import org.distorted.objectlib.main.Cubit;
27
import org.distorted.objectlib.objects.TwistyBandagedCuboid;
28
import org.json.JSONArray;
29
import org.json.JSONException;
30
import org.json.JSONObject;
31

    
32
import org.distorted.library.type.Static3D;
33
import org.distorted.library.type.Static4D;
34

    
35
import org.distorted.objectlib.helpers.ObjectShape;
36
import org.distorted.objectlib.helpers.ObjectSticker;
37
import org.distorted.objectlib.main.ObjectType;
38

    
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40

    
41
public class JsonReader
42
{
43
  private int[][] mAlgorithms;
44
  private int[][] mEdges;
45
  private int[][] mSolvedQuats;
46
  private Static4D[] mQuats;
47
  private int mSolvedFuncIndex;
48
  private int mNumStickerTypes;
49
  private float[][] mCuts;
50
  private boolean[][] mLayerRotatable;
51
  private int mMovementType, mMovementSplit;
52
  private int[][][] mEnabled;
53
  private float[] mDist3D;
54
  private int mNumCubitFaces, mNumFaces, mNumFaceColors;
55
  private float[][] mPositions;
56
  private ObjectShape[] mShapes;
57
  private ObjectFaceShape[] mFaceShapes;
58
  private ObjectVertexEffects[] mVertexEffects;
59
  private Static4D[] mCubitQuats;
60
  private int mNumCubitVariants;
61
  private int[] mCubitVariant;
62
  private int[][] mVariantStickerShape, mVariantFaceIsOuter, mCubitFaceColor;
63
  private ObjectSticker[] mObjectSticker;
64
  private Static3D[] mAxis;
65
  private int[][] mBasicAngle;
66
  private String mLongName, mShortName, mInventor;
67
  private int mYearOfInvention, mComplexity;
68
  private int[] mNumLayers;
69
  private float mSize;
70
  private int mScrambleType, mNumScrambles;
71
  private int mPrice;
72
  private int[] mColor;
73
  private int mInternalColor;
74
  private boolean mResetMaps;
75
  private String mTutorialObject;
76
  private String[][] mTutorials;
77
  private ObjectSignature mSignature;
78
  private int[] mCubitType;
79
  private float[][] mCubitRowOffset;
80
  private ObjectStickerOverride[] mStickerOverrides;
81
  private float mPillowCoeff;
82

    
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

    
85
  private void parseMetadata(JSONObject metadata) throws JSONException
86
    {
87
    mLongName        = metadata.getString("longname");
88
    mShortName       = metadata.getString("shortname");
89
    mInventor        = metadata.getString("inventor");
90
    mYearOfInvention = metadata.getInt("year");
91
    mComplexity      = metadata.getInt("complexity");
92
    mSize            = (float)metadata.getDouble("size");
93
    mNumScrambles    = metadata.getInt("scrambles");
94
    mResetMaps       = metadata.getBoolean("resetmaps");
95
    mNumFaces        = metadata.getInt("num_faces");
96

    
97
    try
98
      {
99
      JSONArray sigArray = metadata.getJSONArray("signature");
100
      int size = sigArray.length();
101
      long[] signature = new long[size];
102
      for(int i=0; i<size; i++) signature[i] = sigArray.getLong(i);
103

    
104
      switch( TwistyBandagedCuboid.getType(mShortName,mLongName) )
105
        {
106
        case 0: mSignature = new ObjectSignature(signature); break;
107
        case 1: mSignature = new ObjectSignature(mShortName,signature); break;
108
        case 2: mSignature = new ObjectSignature("333",signature); break;
109
        }
110
      }
111
    catch(JSONException ex)
112
      {
113
      long signature = metadata.getLong("signature");
114
      mSignature = new ObjectSignature(signature);
115
      }
116

    
117
    boolean free = metadata.optBoolean("free", true);
118

    
119
    if( free ) mPrice = 0;
120
    else mPrice = metadata.optInt("price", ObjectType.DEFAULT_PRICE_OF_OLD_OBJECTS );
121
    }
122

    
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124

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

    
129
    mCubitQuats     = new Static4D[numCubits];
130
    mCubitVariant   = new int[numCubits];
131
    mPositions      = new float[numCubits][];
132
    mCubitFaceColor = new int[numCubits][];
133
    mCubitType      = new int[numCubits];
134
    mCubitRowOffset = new float[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
      mCubitType[i] = jsonCubit.optInt("type", Cubit.TYPE_NORMAL);
159
      float xoff = (float)jsonCubit.optDouble("offsetX", 0 );
160
      float yoff = (float)jsonCubit.optDouble("offsetY", 0 );
161
      float zoff = (float)jsonCubit.optDouble("offsetZ", 0 );
162
      mCubitRowOffset[i] = new float[] {xoff,yoff,zoff};
163
      }
164
    }
165

    
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167

    
168
  private void parseShapes(JSONArray object) throws JSONException
169
    {
170
    mNumCubitVariants     = object.length();
171
    mVariantStickerShape  = new int[mNumCubitVariants][];
172
    mVariantFaceIsOuter   = new int[mNumCubitVariants][];
173
    mShapes               = new ObjectShape[mNumCubitVariants];
174
    mFaceShapes           = new ObjectFaceShape[mNumCubitVariants];
175
    mVertexEffects        = new ObjectVertexEffects[mNumCubitVariants];
176
    float[][][] verts     = new float[mNumCubitVariants][][];
177
    float[][][] bands     = new float[mNumCubitVariants][][];
178
    float[][] convexity   = new float[mNumCubitVariants][];
179
    int[][] bandIndices   = new int[mNumCubitVariants][];
180
    int[][][] vertIndices = new int[mNumCubitVariants][][];
181

    
182
    mNumCubitFaces = -1;
183

    
184
    for(int i=0; i<mNumCubitVariants; i++)
185
      {
186
      JSONObject jsonShape = object.getJSONObject(i);
187

    
188
      ////// vertices /////////////////////////////////////////////////
189
      JSONArray jsonVertices= jsonShape.getJSONArray("vertices");
190
      int numVertices = jsonVertices.length();
191
      verts[i] = new float[numVertices][3];
192

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

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

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

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

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

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

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

    
241
      ////// convexity ///////////////////////////////////////////////
242
      JSONObject jsonConvexity = jsonShape.optJSONObject("convexity");
243

    
244
      if( jsonConvexity!=null )
245
        {
246
        convexity[i] = new float[3];
247
        convexity[i][0] = (float)jsonConvexity.getDouble("x");
248
        convexity[i][1] = (float)jsonConvexity.getDouble("y");
249
        convexity[i][2] = (float)jsonConvexity.getDouble("z");
250
        }
251

    
252
      ////// effects /////////////////////////////////////////////////
253
      JSONArray jsonEffects = jsonShape.optJSONArray("effects");
254

    
255
      if( jsonEffects!=null )
256
        {
257
        int numEffects = jsonEffects.length();
258

    
259
        String[] name    = new String[numEffects];
260
        float[][] vars   = new float[numEffects][5];
261
        float[][] center = new float[numEffects][3];
262
        float[][] region = new float[numEffects][4];
263
        boolean[] use    = new boolean[numEffects];
264

    
265
        for(int j=0; j<numEffects; j++)
266
          {
267
          JSONObject jsonEffect = jsonEffects.getJSONObject(j);
268

    
269
          name[j] = jsonEffect.getString("name");
270

    
271
          vars[j][0] = (float)jsonEffect.getDouble("var0");
272
          vars[j][1] = (float)jsonEffect.getDouble("var1");
273
          vars[j][2] = (float)jsonEffect.getDouble("var2");
274
          vars[j][3] = (float)jsonEffect.getDouble("var3");
275
          vars[j][4] = (float)jsonEffect.getDouble("var4");
276

    
277
          center[j][0] = (float)jsonEffect.getDouble("center0");
278
          center[j][1] = (float)jsonEffect.getDouble("center1");
279
          center[j][2] = (float)jsonEffect.getDouble("center2");
280

    
281
          region[j][0] = (float)jsonEffect.getDouble("region0");
282
          region[j][1] = (float)jsonEffect.getDouble("region1");
283
          region[j][2] = (float)jsonEffect.getDouble("region2");
284
          region[j][3] = (float)jsonEffect.getDouble("region3");
285

    
286
          use[j] = jsonEffect.getBoolean("use");
287
          }
288

    
289
        mVertexEffects[i] = new ObjectVertexEffects(name,vars,center,region,use);
290
        }
291
      }
292

    
293
    for(int i=0; i<mNumCubitVariants; i++)
294
      {
295
      mShapes[i] = new ObjectShape(verts[i],vertIndices[i]);
296
      mFaceShapes[i] = new ObjectFaceShape(bands[i],bandIndices[i],convexity[i]);
297
      }
298
    }
299

    
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301

    
302
  private void parseStickers(JSONArray object) throws JSONException
303
    {
304
    mNumStickerTypes = object.length();
305
    mObjectSticker = new ObjectSticker[mNumStickerTypes];
306

    
307
    for(int i=0; i<mNumStickerTypes; i++)
308
      {
309
      JSONObject sticker = object.getJSONObject(i);
310
      float stroke = (float)sticker.getDouble("stroke");
311
      JSONArray vertices = sticker.getJSONArray("vertices");
312
      int numVertices = vertices.length();
313

    
314
      float[] coords     = new float[2*numVertices];
315
      float[] curvatures = new float[numVertices];
316
      float[] radii      = new float[numVertices];
317

    
318
      for(int j=0; j<numVertices; j++)
319
        {
320
        JSONObject vertex = vertices.getJSONObject(j);
321

    
322
        coords[2*j  ] = (float)vertex.getDouble("x");
323
        coords[2*j+1] = (float)vertex.getDouble("y");
324
        curvatures[j] = (float)vertex.getDouble("angle");
325
        radii[j]      = (float)vertex.getDouble("radius");
326
        }
327

    
328
      mObjectSticker[i] = new ObjectSticker(coords,curvatures,radii,stroke);
329
      }
330
    }
331

    
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333

    
334
  private void parseOverrides(JSONArray object) throws JSONException
335
    {
336
    if( object!=null )
337
      {
338
      int numOverrides = object.length();
339
      mStickerOverrides= new ObjectStickerOverride[numOverrides];
340

    
341
      for(int i=0; i<numOverrides; i++)
342
        {
343
        JSONObject override  = object.getJSONObject(i);
344
        JSONArray cubitArray = override.getJSONArray("cubitfaces");
345
        int color = override.getInt("color");
346
        int numCubits = cubitArray.length();
347
        int[] cubitface = new int[numCubits];
348
        for(int j=0; j<numCubits; j++) cubitface[j] = cubitArray.getInt(j);
349
        mStickerOverrides[i] = new ObjectStickerOverride(cubitface,color);
350
        }
351
      }
352
    else
353
      {
354
      mStickerOverrides = null;
355
      }
356
    }
357

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

    
360
  private void parseMesh(JSONObject object) throws JSONException
361
    {
362
    JSONArray cubits   = object.getJSONArray("cubits");
363
    parseCubits(cubits);
364
    JSONArray shapes   = object.getJSONArray("shapes");
365
    parseShapes(shapes);
366
    JSONArray stickers = object.getJSONArray("stickers");
367
    parseStickers(stickers);
368

    
369
    JSONArray overrides= object.optJSONArray("overrides");
370
    parseOverrides(overrides);
371

    
372
    mPillowCoeff = (float)object.optDouble("pillow",1.0);
373
    }
374

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

    
377
  private void parseAxis(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 jsonAlgorithms = object.getJSONArray("algorithms");
445
      int numAlgs = jsonAlgorithms.length();
446
      mAlgorithms = new int[numAlgs][];
447

    
448
      for(int i=0; i<numAlgs; i++)
449
        {
450
        JSONArray jsonAlg = jsonAlgorithms.getJSONArray(i);
451
        int numEntries = jsonAlg.length();
452
        for(int j=0; j<numEntries; j++) mAlgorithms[i][j] = jsonAlg.getInt(j);
453
        }
454

    
455
      JSONArray jsonEdges = object.getJSONArray("edges");
456
      int numEdges = jsonEdges.length();
457
      mEdges = new int[numEdges][];
458

    
459
      for(int i=0; i<numEdges; i++)
460
        {
461
        JSONArray jsonEdge = jsonEdges.getJSONArray(i);
462
        int numEntries = jsonEdge.length();
463
        for(int j=0; j<numEntries; j++) mEdges[i][j] = jsonEdge.getInt(j);
464
        }
465
      }
466
    }
467

    
468
///////////////////////////////////////////////////////////////////////////////////////////////////
469

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

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

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

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

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

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

    
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516

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

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

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

    
527
///////////////////////////////////////////////////////////////////////////////////////////////////
528

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

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

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

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

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

    
575
///////////////////////////////////////////////////////////////////////////////////////////////////
576

    
577
  private void parseTutorial(JSONObject object) throws JSONException
578
    {
579
    mTutorialObject = object.getString("object");
580
    JSONArray tuts= object.getJSONArray("tutorials");
581

    
582
    int len = tuts.length();
583
    mTutorials = new String[len][4];
584

    
585
    for(int i=0; i<len; i++)
586
      {
587
      JSONObject tut = tuts.getJSONObject(i);
588
      mTutorials[i][0] = tut.getString("language");
589
      mTutorials[i][1] = tut.getString("link");
590
      mTutorials[i][2] = tut.getString("title");
591
      mTutorials[i][3] = tut.getString("author");
592
      }
593
    }
594

    
595
///////////////////////////////////////////////////////////////////////////////////////////////////
596
// PUBLIC
597
///////////////////////////////////////////////////////////////////////////////////////////////////
598

    
599
  public void parseJsonFile(InputStream jsonStream) throws JSONException, IOException
600
    {
601
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
602
    StringBuilder contents = new StringBuilder();
603
    String line;
604

    
605
    while( (line = br.readLine()) != null) contents.append(line);
606
    br.close();
607
    jsonStream.close();
608
    String contentsString = contents.toString();
609
    JSONObject object = new JSONObject(contentsString);
610
    int major = object.getInt("major");
611

    
612
    if( major==6 )
613
      {
614
      parseFile(object);
615
      }
616
    else
617
      {
618
      android.util.Log.e("readJsonFile", "Unknown version "+major);
619
      }
620
    }
621

    
622
///////////////////////////////////////////////////////////////////////////////////////////////////
623

    
624
  public void parseJsonFileMetadata(InputStream jsonStream) throws JSONException, IOException
625
    {
626
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
627
    StringBuilder contents = new StringBuilder();
628
    String tmp;
629

    
630
    while( (tmp = br.readLine()) != null) contents.append(tmp);
631
    br.close();
632
    jsonStream.close();
633

    
634
    JSONObject object = new JSONObject(contents.toString());
635
    int major = object.getInt("major");
636

    
637
    if( major==6 )
638
      {
639
      JSONObject metadata = object.getJSONObject("metadata");
640
      parseMetadata(metadata);
641
      }
642
    else
643
      {
644
      android.util.Log.e("readJsonFileQuick", "Unknown version "+major);
645
      }
646
    }
647

    
648
///////////////////////////////////////////////////////////////////////////////////////////////////
649

    
650
  public void readNumScramblesAndPrice(Context context, String fileName) throws IOException, JSONException
651
    {
652
    File file = new File(context.getFilesDir(), fileName);
653
    InputStream stream = new FileInputStream(file);
654
    BufferedReader br = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
655

    
656
    StringBuilder contents = new StringBuilder();
657
    String tmp;
658
    while( (tmp = br.readLine()) != null) contents.append(tmp);
659
    br.close();
660
    stream.close();
661

    
662
    JSONObject object = new JSONObject(contents.toString());
663
    JSONObject metadata = object.getJSONObject("metadata");
664
    mNumScrambles = metadata.getInt("scrambles");
665

    
666
    boolean free = metadata.optBoolean("free",true);
667
    if( free ) mPrice = 0;
668
    else mPrice = metadata.optInt("price", ObjectType.DEFAULT_PRICE_OF_OLD_OBJECTS );
669
    }
670

    
671
///////////////////////////////////////////////////////////////////////////////////////////////////
672

    
673
  public void parseJsonTutorial(InputStream jsonStream) throws IOException, JSONException
674
    {
675
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
676
    StringBuilder contents = new StringBuilder();
677
    String tmp;
678

    
679
    while( (tmp = br.readLine()) != null) contents.append(tmp);
680
    br.close();
681
    jsonStream.close();
682

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

    
686
    if( major==1 )
687
      {
688
      parseTutorial(object);
689
      }
690
    else
691
      {
692
      android.util.Log.e("readJsonFile", "Unknown tutorial version "+major);
693
      }
694
    }
695

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

    
698
  public int getScrambleType()
699
    {
700
    return mScrambleType;
701
    }
702

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

    
705
  public int[][] getScrambleEdges()
706
    {
707
    return mEdges;
708
    }
709

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

    
712
  public int[][] getScrambleAlgorithms()
713
    {
714
    return mAlgorithms;
715
    }
716

    
717
///////////////////////////////////////////////////////////////////////////////////////////////////
718

    
719
  public int[][] getSolvedQuats()
720
    {
721
    return mSolvedQuats;
722
    }
723

    
724
///////////////////////////////////////////////////////////////////////////////////////////////////
725

    
726
  public Static4D[] getQuats()
727
    {
728
    return mQuats;
729
    }
730

    
731
///////////////////////////////////////////////////////////////////////////////////////////////////
732

    
733
  public int getSolvedFunctionIndex()
734
    {
735
    return mSolvedFuncIndex;
736
    }
737

    
738
///////////////////////////////////////////////////////////////////////////////////////////////////
739

    
740
  public int getNumStickerTypes()
741
    {
742
    return mNumStickerTypes;
743
    }
744

    
745
///////////////////////////////////////////////////////////////////////////////////////////////////
746

    
747
  public float[][] getCuts()
748
    {
749
    return mCuts;
750
    }
751

    
752
///////////////////////////////////////////////////////////////////////////////////////////////////
753

    
754
  public boolean[][] getLayerRotatable()
755
    {
756
    return mLayerRotatable;
757
    }
758

    
759
///////////////////////////////////////////////////////////////////////////////////////////////////
760

    
761
  public int getMovementType()
762
    {
763
    return mMovementType;
764
    }
765

    
766
///////////////////////////////////////////////////////////////////////////////////////////////////
767

    
768
  public int getMovementSplit()
769
    {
770
    return mMovementSplit;
771
    }
772

    
773
///////////////////////////////////////////////////////////////////////////////////////////////////
774

    
775
  public int[][][] getEnabled()
776
    {
777
    return mEnabled;
778
    }
779

    
780
///////////////////////////////////////////////////////////////////////////////////////////////////
781

    
782
  public float[] getDist3D()
783
    {
784
    return mDist3D;
785
    }
786

    
787
///////////////////////////////////////////////////////////////////////////////////////////////////
788

    
789
  public int getNumCubitFaces()
790
    {
791
    return mNumCubitFaces;
792
    }
793

    
794
///////////////////////////////////////////////////////////////////////////////////////////////////
795

    
796
  public float[][] getCubitPositions()
797
    {
798
    return mPositions;
799
    }
800

    
801
///////////////////////////////////////////////////////////////////////////////////////////////////
802

    
803
  public ObjectShape getObjectShape(int variant)
804
    {
805
    return mShapes[variant];
806
    }
807

    
808
///////////////////////////////////////////////////////////////////////////////////////////////////
809

    
810
  public ObjectFaceShape getObjectFaceShape(int variant)
811
    {
812
    return mFaceShapes[variant];
813
    }
814

    
815
///////////////////////////////////////////////////////////////////////////////////////////////////
816

    
817
  public ObjectVertexEffects getVertexEffects(int variant)
818
    {
819
    return mVertexEffects[variant];
820
    }
821

    
822
///////////////////////////////////////////////////////////////////////////////////////////////////
823

    
824
  public Static4D getCubitQuats(int cubit)
825
    {
826
    return mCubitQuats[cubit];
827
    }
828

    
829
///////////////////////////////////////////////////////////////////////////////////////////////////
830

    
831
  public int getNumCubitVariants()
832
    {
833
    return mNumCubitVariants;
834
    }
835

    
836
///////////////////////////////////////////////////////////////////////////////////////////////////
837

    
838
  public int getCubitVariant(int cubit)
839
    {
840
    return mCubitVariant[cubit];
841
    }
842

    
843
///////////////////////////////////////////////////////////////////////////////////////////////////
844

    
845
  public int getVariantStickerShape(int variant, int face)
846
    {
847
    int[] shapes = mVariantStickerShape[variant];
848
    return shapes.length>face ? shapes[face] : -1;
849
    }
850

    
851
///////////////////////////////////////////////////////////////////////////////////////////////////
852

    
853
  public int[] getCubitTypes()
854
    {
855
    return mCubitType;
856
    }
857

    
858
///////////////////////////////////////////////////////////////////////////////////////////////////
859

    
860
  public float[][] getCubitOffsets()
861
    {
862
    return mCubitRowOffset;
863
    }
864

    
865
///////////////////////////////////////////////////////////////////////////////////////////////////
866

    
867
  public int[][] getVariantFaceIsOuter()
868
    {
869
    return mVariantFaceIsOuter;
870
    }
871

    
872
///////////////////////////////////////////////////////////////////////////////////////////////////
873

    
874
  public int getCubitFaceFace(int cubit, int face)
875
    {
876
    return mCubitFaceColor[cubit][face];
877
    }
878

    
879
///////////////////////////////////////////////////////////////////////////////////////////////////
880

    
881
  public int getNumScrambles()
882
    {
883
    return mNumScrambles;
884
    }
885

    
886
///////////////////////////////////////////////////////////////////////////////////////////////////
887

    
888
  public int getPrice()
889
    {
890
    return mPrice;
891
    }
892

    
893
///////////////////////////////////////////////////////////////////////////////////////////////////
894

    
895
  public ObjectSticker retSticker(int sticker)
896
    {
897
    return mObjectSticker[sticker];
898
    }
899

    
900
///////////////////////////////////////////////////////////////////////////////////////////////////
901

    
902
  public ObjectStickerOverride[] getStickerOverrides()
903
    {
904
    return mStickerOverrides;
905
    }
906

    
907
///////////////////////////////////////////////////////////////////////////////////////////////////
908

    
909
  public float getPillowCoeff()
910
    {
911
    return mPillowCoeff;
912
    }
913

    
914
///////////////////////////////////////////////////////////////////////////////////////////////////
915

    
916
  public Static3D[] getRotationAxis()
917
    {
918
    return mAxis;
919
    }
920

    
921
///////////////////////////////////////////////////////////////////////////////////////////////////
922

    
923
  public int[][] getBasicAngle()
924
    {
925
    return mBasicAngle;
926
    }
927

    
928
///////////////////////////////////////////////////////////////////////////////////////////////////
929

    
930
  public ObjectSignature getSignature()
931
    {
932
    return mSignature;
933
    }
934

    
935
///////////////////////////////////////////////////////////////////////////////////////////////////
936

    
937
  public String getObjectName()
938
    {
939
    return mLongName;
940
    }
941

    
942
///////////////////////////////////////////////////////////////////////////////////////////////////
943

    
944
  public String getShortName()
945
    {
946
    return mShortName;
947
    }
948

    
949
///////////////////////////////////////////////////////////////////////////////////////////////////
950

    
951
  public String getInventor()
952
    {
953
    return mInventor;
954
    }
955

    
956
///////////////////////////////////////////////////////////////////////////////////////////////////
957

    
958
  public int getYearOfInvention()
959
    {
960
    return mYearOfInvention;
961
    }
962

    
963
///////////////////////////////////////////////////////////////////////////////////////////////////
964

    
965
  public int getComplexity()
966
    {
967
    return mComplexity;
968
    }
969

    
970
///////////////////////////////////////////////////////////////////////////////////////////////////
971

    
972
  public int getNumFaces()
973
    {
974
    return mNumFaces;
975
    }
976

    
977
///////////////////////////////////////////////////////////////////////////////////////////////////
978

    
979
  public int getNumFaceColors()
980
    {
981
    return mNumFaceColors;
982
    }
983

    
984
///////////////////////////////////////////////////////////////////////////////////////////////////
985

    
986
  public int[] getNumLayers()
987
    {
988
    return mNumLayers;
989
    }
990

    
991
///////////////////////////////////////////////////////////////////////////////////////////////////
992

    
993
  public float getSize()
994
    {
995
    return mSize;
996
    }
997

    
998
///////////////////////////////////////////////////////////////////////////////////////////////////
999

    
1000
  public int getColor(int face)
1001
    {
1002
    return mColor[face];
1003
    }
1004

    
1005
///////////////////////////////////////////////////////////////////////////////////////////////////
1006

    
1007
  public int getInternalColor()
1008
    {
1009
    return mInternalColor;
1010
    }
1011

    
1012
///////////////////////////////////////////////////////////////////////////////////////////////////
1013

    
1014
  public boolean shouldResetTextureMaps()
1015
    {
1016
    return mResetMaps;
1017
    }
1018

    
1019
///////////////////////////////////////////////////////////////////////////////////////////////////
1020

    
1021
  public String getTutorialObject()
1022
    {
1023
    return mTutorialObject;
1024
    }
1025

    
1026
///////////////////////////////////////////////////////////////////////////////////////////////////
1027

    
1028
  public String[][] getTutorials()
1029
    {
1030
    return mTutorials;
1031
    }
1032
}
(1-1/2)