'use strict';

var I = require('immutable');


var _BASE_LENGTH = I.Range(1)
  .filter(function(n) {
    if (n % 2)
      return false;
    var b = Math.pow(10, n);
    return 2 * b - 2 == 2 * b - 1 || -2 * b + 2 == -2 * b + 1;
  }).first() - 1;

var _BASE = Math.pow(10, _BASE_LENGTH);
var _HALFBASE = Math.sqrt(_BASE);


var _asNum = function(n) {
  return Math.abs(n) < _BASE ? _makeCheckedInt(n) : _longIntFromNative(n);
};


var num = function(n) {
  if (n == null)
    return num.fromNative(0);
  else if (typeof n == "number")
    return num.fromNative(n);
  else if (typeof n == "string")
    return num.parse(n);
  else {
    if (n instanceof NumberBase)
      return n;
    else
      throw new Error("expected a number, got "+n);
  }
};


num.fromNative = function(n) {
  if (n % 1)
    throw new Error("expected an integer, got "+n);
  return _asNum(n);
};


num.parse = function(n) {
  if (!n.match(/^[+-]?\d+$/))
    throw new Error("expected an integer literal, got "+n);

  var s = 1, m = n;
  if (n[0] == "+")
    m = n.slice(1);
  else if (n[0] == "-") {
    s = -1;
    m = n.slice(1);
  }

  if (m.length <= _BASE_LENGTH)
    return _makeCheckedInt(parseInt(n));
  else {
    var a = m.length % _BASE_LENGTH;
    var b = m.length / _BASE_LENGTH;
    var sections = I.List(I.Range(0, b-1).map(function(i) {
      return [a + i * _BASE_LENGTH, a + (i+1) * _BASE_LENGTH];
    }));
    if (a > 0)
      sections = sections.unshift([0, a]);

    return _makeLongInt(s, sections.map(function(r) {
      return parseInt(m.slice(r[0], r[1]));
    }));
  }
};


var _makeLongInt = function(s, a) {
  console.log(s, a);
};


num.parse("1234567890123456789012345678901234567890123456789012");

@@ -1234,24 +1234,25 @@
 var b = 
+(
 m.length
  / _BASE
@@ -1243,16 +1243,21 @@
 m.length
+ - a)
  / _BASE
@@ -1303,14 +1303,12 @@
 nge(
-0, b-1
+b, 0
 ).ma
@@ -1341,17 +1341,21 @@
 rn %5Ba + 
-i
+(i-1)
  * _BASE
@@ -1371,13 +1371,9 @@
 a + 
-(i+1)
+i
  * _
@@ -1440,15 +1440,12 @@
 ons.
-unshift
+push
 (%5B0,
@@ -1462,28 +1462,28 @@
  return 
-_make
 LongInt
+.make
 (s, sect
@@ -1571,21 +1571,16 @@
 ;%0A%0A%0Avar 
-_make
 LongInt 
@@ -1580,16 +1580,26 @@
 ongInt =
+ %7B%0A  make:
  functio
@@ -1610,16 +1610,107 @@
  a) %7B%0A  
+  return %7B%0A      type  : LongInt,%0A      sign  : a ? s : 0,%0A      digits: a%0A    %7D;%0A  %7D%0A%7D;%0A%0A%0A
 console.
@@ -1717,20 +1717,8 @@
 log(
-s, a);%0A%7D;%0A%0A%0A
 num.
@@ -1725,33 +1725,32 @@
 parse(%22123456789
-0
 1234567890123456
@@ -1734,33 +1734,32 @@
 3456789123456789
-0
 1234567890123456
@@ -1743,33 +1743,32 @@
 3456789123456789
-0
 1234567890123456
@@ -1760,17 +1760,16 @@
 23456789
-0
 12345678
@@ -1773,11 +1773,14 @@
 6789
-0
 12
-%22
+345%22)
 );%0A

fix long int parsing