Project

General

Profile

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

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

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
        mAlgorithms[i] = new int[numEntries];
453
        for(int j=0; j<numEntries; j++) mAlgorithms[i][j] = jsonAlg.getInt(j);
454
        }
455

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

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

    
470
///////////////////////////////////////////////////////////////////////////////////////////////////
471

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

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

    
482
      mEnabled = new int[numFace][][];
483

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

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

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

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

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

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

    
526
    mInternalColor = object.getInt(mNumFaceColors);
527
    }
528

    
529
///////////////////////////////////////////////////////////////////////////////////////////////////
530

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

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

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

    
555
///////////////////////////////////////////////////////////////////////////////////////////////////
556

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

    
577
///////////////////////////////////////////////////////////////////////////////////////////////////
578

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

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

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

    
597
///////////////////////////////////////////////////////////////////////////////////////////////////
598
// PUBLIC
599
///////////////////////////////////////////////////////////////////////////////////////////////////
600

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

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

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

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

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

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

    
636
    JSONObject object = new JSONObject(contents.toString());
637
    int major = object.getInt("major");
638

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

    
650
///////////////////////////////////////////////////////////////////////////////////////////////////
651

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

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

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

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

    
673
///////////////////////////////////////////////////////////////////////////////////////////////////
674

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

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

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

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

    
698
///////////////////////////////////////////////////////////////////////////////////////////////////
699

    
700
  public int getScrambleType()
701
    {
702
    return mScrambleType;
703
    }
704

    
705
///////////////////////////////////////////////////////////////////////////////////////////////////
706

    
707
  public int[][] getScrambleEdges()
708
    {
709
    return mEdges;
710
    }
711

    
712
///////////////////////////////////////////////////////////////////////////////////////////////////
713

    
714
  public int[][] getScrambleAlgorithms()
715
    {
716
    return mAlgorithms;
717
    }
718

    
719
///////////////////////////////////////////////////////////////////////////////////////////////////
720

    
721
  public int[][] getSolvedQuats()
722
    {
723
    return mSolvedQuats;
724
    }
725

    
726
///////////////////////////////////////////////////////////////////////////////////////////////////
727

    
728
  public Static4D[] getQuats()
729
    {
730
    return mQuats;
731
    }
732

    
733
///////////////////////////////////////////////////////////////////////////////////////////////////
734

    
735
  public int getSolvedFunctionIndex()
736
    {
737
    return mSolvedFuncIndex;
738
    }
739

    
740
///////////////////////////////////////////////////////////////////////////////////////////////////
741

    
742
  public int getNumStickerTypes()
743
    {
744
    return mNumStickerTypes;
745
    }
746

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

    
749
  public float[][] getCuts()
750
    {
751
    return mCuts;
752
    }
753

    
754
///////////////////////////////////////////////////////////////////////////////////////////////////
755

    
756
  public boolean[][] getLayerRotatable()
757
    {
758
    return mLayerRotatable;
759
    }
760

    
761
///////////////////////////////////////////////////////////////////////////////////////////////////
762

    
763
  public int getMovementType()
764
    {
765
    return mMovementType;
766
    }
767

    
768
///////////////////////////////////////////////////////////////////////////////////////////////////
769

    
770
  public int getMovementSplit()
771
    {
772
    return mMovementSplit;
773
    }
774

    
775
///////////////////////////////////////////////////////////////////////////////////////////////////
776

    
777
  public int[][][] getEnabled()
778
    {
779
    return mEnabled;
780
    }
781

    
782
///////////////////////////////////////////////////////////////////////////////////////////////////
783

    
784
  public float[] getDist3D()
785
    {
786
    return mDist3D;
787
    }
788

    
789
///////////////////////////////////////////////////////////////////////////////////////////////////
790

    
791
  public int getNumCubitFaces()
792
    {
793
    return mNumCubitFaces;
794
    }
795

    
796
///////////////////////////////////////////////////////////////////////////////////////////////////
797

    
798
  public float[][] getCubitPositions()
799
    {
800
    return mPositions;
801
    }
802

    
803
///////////////////////////////////////////////////////////////////////////////////////////////////
804

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

    
810
///////////////////////////////////////////////////////////////////////////////////////////////////
811

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

    
817
///////////////////////////////////////////////////////////////////////////////////////////////////
818

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

    
824
///////////////////////////////////////////////////////////////////////////////////////////////////
825

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

    
831
///////////////////////////////////////////////////////////////////////////////////////////////////
832

    
833
  public int getNumCubitVariants()
834
    {
835
    return mNumCubitVariants;
836
    }
837

    
838
///////////////////////////////////////////////////////////////////////////////////////////////////
839

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

    
845
///////////////////////////////////////////////////////////////////////////////////////////////////
846

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

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

    
855
  public int[] getCubitTypes()
856
    {
857
    return mCubitType;
858
    }
859

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

    
862
  public float[][] getCubitOffsets()
863
    {
864
    return mCubitRowOffset;
865
    }
866

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

    
869
  public int[][] getVariantFaceIsOuter()
870
    {
871
    return mVariantFaceIsOuter;
872
    }
873

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

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

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

    
883
  public int getNumScrambles()
884
    {
885
    return mNumScrambles;
886
    }
887

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

    
890
  public int getPrice()
891
    {
892
    return mPrice;
893
    }
894

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

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

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

    
904
  public ObjectStickerOverride[] getStickerOverrides()
905
    {
906
    return mStickerOverrides;
907
    }
908

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

    
911
  public float getPillowCoeff()
912
    {
913
    return mPillowCoeff;
914
    }
915

    
916
///////////////////////////////////////////////////////////////////////////////////////////////////
917

    
918
  public Static3D[] getRotationAxis()
919
    {
920
    return mAxis;
921
    }
922

    
923
///////////////////////////////////////////////////////////////////////////////////////////////////
924

    
925
  public int[][] getBasicAngle()
926
    {
927
    return mBasicAngle;
928
    }
929

    
930
///////////////////////////////////////////////////////////////////////////////////////////////////
931

    
932
  public ObjectSignature getSignature()
933
    {
934
    return mSignature;
935
    }
936

    
937
///////////////////////////////////////////////////////////////////////////////////////////////////
938

    
939
  public String getObjectName()
940
    {
941
    return mLongName;
942
    }
943

    
944
///////////////////////////////////////////////////////////////////////////////////////////////////
945

    
946
  public String getShortName()
947
    {
948
    return mShortName;
949
    }
950

    
951
///////////////////////////////////////////////////////////////////////////////////////////////////
952

    
953
  public String getInventor()
954
    {
955
    return mInventor;
956
    }
957

    
958
///////////////////////////////////////////////////////////////////////////////////////////////////
959

    
960
  public int getYearOfInvention()
961
    {
962
    return mYearOfInvention;
963
    }
964

    
965
///////////////////////////////////////////////////////////////////////////////////////////////////
966

    
967
  public int getComplexity()
968
    {
969
    return mComplexity;
970
    }
971

    
972
///////////////////////////////////////////////////////////////////////////////////////////////////
973

    
974
  public int getNumFaces()
975
    {
976
    return mNumFaces;
977
    }
978

    
979
///////////////////////////////////////////////////////////////////////////////////////////////////
980

    
981
  public int getNumFaceColors()
982
    {
983
    return mNumFaceColors;
984
    }
985

    
986
///////////////////////////////////////////////////////////////////////////////////////////////////
987

    
988
  public int[] getNumLayers()
989
    {
990
    return mNumLayers;
991
    }
992

    
993
///////////////////////////////////////////////////////////////////////////////////////////////////
994

    
995
  public float getSize()
996
    {
997
    return mSize;
998
    }
999

    
1000
///////////////////////////////////////////////////////////////////////////////////////////////////
1001

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

    
1007
///////////////////////////////////////////////////////////////////////////////////////////////////
1008

    
1009
  public int getInternalColor()
1010
    {
1011
    return mInternalColor;
1012
    }
1013

    
1014
///////////////////////////////////////////////////////////////////////////////////////////////////
1015

    
1016
  public boolean shouldResetTextureMaps()
1017
    {
1018
    return mResetMaps;
1019
    }
1020

    
1021
///////////////////////////////////////////////////////////////////////////////////////////////////
1022

    
1023
  public String getTutorialObject()
1024
    {
1025
    return mTutorialObject;
1026
    }
1027

    
1028
///////////////////////////////////////////////////////////////////////////////////////////////////
1029

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