import numpy as np
import json
import base64

class numpyEncoder(json.JSONEncoder):

    def default(self, obj):
        if isinstance(obj, np.ndarray):
            if obj.flags['C_CONTIGUOUS']:
                obj_data = obj.data
            else:
                cont_obj = np.ascontiguousarray(obj)
                assert(cont_obj.flags['C_CONTIGUOUS'])
                obj_data = cont_obj.data
            data_b64 = base64.b64encode(obj_data)
            return dict(__ndarray__=data_b64,
                        dtype=str(obj.dtype),
                        shape=obj.shape)
        return json.JSONEncoder(self, obj)

def numpyDecoder(obj):
    if isinstance(obj, dict) and '__ndarray__' in obj:
        data = base64.b64decode(obj['__ndarray__'])
        return np.frombuffer(data, obj['dtype']).reshape(obj['shape'])
    return obj

def jsonEncoder(array_data):
    return json.dumps(array_data, cls=numpyEncoder)

def jsonDecoder(json_data):
    _array=None
    try:
        _array=json.loads(json_data, object_hook=numpyDecoder)
        #_array=int(json.loads(json_data, object_hook=numpyDecoder))
    except:
        _array=None

    return _array

# convert list/np.array to json
def array2json(array_data):
    if type(list_data)==list:
        return json.dumps(np.array(list_data))
    elif type(list_data)==np.ndarray:
        return json.dumps(list_data)
    else:
        print "Error: not proper data type."
        return None

# convert json to list
def json2array(json_data):
    try:
        return np.array(json.loads(json_data))
    except:
        print "Error: json string is not in list type."
        return None