# Path: speriment/compiler.py
# class ExperimentEncoder(json.JSONEncoder):
#     '''This class enables nested Python objects to be correctly serialized to JSON.
#     It also requires that non-schema validation pass before the JSON is
#     generated.'''
#     def default(self, obj):
#         obj._validate()
#         new_obj = copy.deepcopy(obj)
#         try:
#             return new_obj.comp().__dict__
#         except:
#             # Let the base class default method raise the TypeError
#             return json.JSONEncoder.default(self, new_obj.__dict__)
# 
# Path: speriment/utils.py
# def make_exp(filename):
#     '''Add script tags to PsiTurk's exp.html file so it can use speriment.js and
#     the JSON object, and add css link so it can use speriment.css.'''
#     exp_file = './templates/exp.html'
#     #TODO will change to static/lib/node_modules/speriment/speriment.js and maybe min
#     speriment_tag = '''\n\t\t<script src="/static/lib/node_modules/speriment/javascript/speriment.js" type="text/javascript">'''
#     json_tag = '''\n\t\t<script src="/static/js/{0}" type="text/javascript">'''.format(filename)
#     script_divider = '</script>'
#     css_tag = '''\n\t<link rel=stylesheet href="/static/lib/node_modules/speriment/css/speriment.css"'''
#     css_divider = 'type="text/css">'
#     new_contents = None
#     with open(exp_file, 'r') as exp:
#         exp_contents = exp.read()
#         script_tags = exp_contents.split(script_divider)
#         # These scripts must go after PsiTurk and its dependencies but before
#         # task.js and the rest of the page
#         if script_tags[-4] == speriment_tag:
#             script_tags[-3] = json_tag
#         else:
#             script_tags = script_tags[:-2] + [speriment_tag] + [json_tag] + script_tags[-2:]
#         with_scripts = script_divider.join(script_tags)
#         contents = with_scripts.split(css_divider)
#         if contents[-2] != css_tag:
#             contents = contents[:-1] + [css_tag] + [contents[-1]]
#         new_contents = css_divider.join(contents)
#     with open(exp_file, 'w') as expw:
#         expw.write(new_contents)
# 
# def make_task(varname):
#     '''Replace PsiTurk's example task.js with the standard Speriment task.js,
#     with the JSON object variable name inserted.'''
#     with open('./static/js/task.js', 'w') as task:
#         task.write('''$(document).ready(function(){
#     var mySperiment = ''' + varname + ''';
#     var psiturk = PsiTurk(uniqueId, adServerLoc);
#     psiturk.finishInstructions();
#     var speriment = new Experiment(mySperiment, condition, counterbalance, psiturk);
#     speriment.start();
# });''')
# 
# class IDGenerator:
#     '''Creates an object to generate unique IDs for experimental components. You
#     should create exactly one per experiment so that all IDs in that experiment
#     will be distinct.
# 
#     Usage:
#     with make_experiment(IDGenerator()):
#         <experiment code>
#     '''
# 
#     def __init__(self, seed = -1):
#         '''seed: optional, an integer to start making IDs at.'''
#         self.current_id = seed
# 
#     def _current(self):
#         return self.current_id
# 
#     def _next_id(self):
#         '''Takes no arguments and returns a string, which is a new unique ID.'''
#         self.current_id += 1
#         return str(self.current_id)


from component import Component
from sample_from import SampleFrom
from speriment.compiler import ExperimentEncoder
from speriment.utils import make_exp, make_task, IDGenerator
import pkg_resources, json, jsonschema, copy
                if not all(sampler.field in fields for sampler in samplers):
                    for sampler in samplers:
                        if sampler.field not in fields:
                            raise ValueError('''Attempt to sample {} field from {}, which is not among its fields'''.format(sampler.field, bank_name))

    def _validate_json(self, json_object):
        contents = pkg_resources.resource_string(__name__, 'sperimentschema.json')
        schema = json.loads(contents)
        jsonschema.validate(json_object, schema)

    def to_JSON(self):
        SampleFrom._compile_time_generators = copy.deepcopy(SampleFrom._id_generators)
        return json.dumps(self, indent = 4, cls = ExperimentEncoder)

    def to_file(self, filename, varname):
        '''validates the structure of the experiment and writes it as a JSON
        object in a JavaScript file.'''
        json_experiment = self.to_JSON()
        self._validate_json(json_experiment)
        to_write = 'var ' + varname + ' = ' + json_experiment
        with open(filename, 'w') as f:
            f.write(to_write)

    def install(self, experiment_name):
        '''validates the structure of the experiment, writes it as a JSON object
        in a JavaScript file, and gives PsiTurk access to Speriment and the JSON
        object.'''
        filename = experiment_name + '.js'
        varname = experiment_name
        self.to_file('./static/js/' + filename, varname)

# Path: speriment/compiler.py
# class ExperimentEncoder(json.JSONEncoder):
#     '''This class enables nested Python objects to be correctly serialized to JSON.
#     It also requires that non-schema validation pass before the JSON is
#     generated.'''
#     def default(self, obj):
#         obj._validate()
#         new_obj = copy.deepcopy(obj)
#         try:
#             return new_obj.comp().__dict__
#         except:
#             # Let the base class default method raise the TypeError
#             return json.JSONEncoder.default(self, new_obj.__dict__)
# 
# Path: speriment/utils.py
# def make_exp(filename):
#     '''Add script tags to PsiTurk's exp.html file so it can use speriment.js and
#     the JSON object, and add css link so it can use speriment.css.'''
#     exp_file = './templates/exp.html'
#     #TODO will change to static/lib/node_modules/speriment/speriment.js and maybe min
#     speriment_tag = '''\n\t\t<script src="/static/lib/node_modules/speriment/javascript/speriment.js" type="text/javascript">'''
#     json_tag = '''\n\t\t<script src="/static/js/{0}" type="text/javascript">'''.format(filename)
#     script_divider = '</script>'
#     css_tag = '''\n\t<link rel=stylesheet href="/static/lib/node_modules/speriment/css/speriment.css"'''
#     css_divider = 'type="text/css">'
#     new_contents = None
#     with open(exp_file, 'r') as exp:
#         exp_contents = exp.read()
#         script_tags = exp_contents.split(script_divider)
#         # These scripts must go after PsiTurk and its dependencies but before
#         # task.js and the rest of the page
#         if script_tags[-4] == speriment_tag:
#             script_tags[-3] = json_tag
#         else:
#             script_tags = script_tags[:-2] + [speriment_tag] + [json_tag] + script_tags[-2:]
#         with_scripts = script_divider.join(script_tags)
#         contents = with_scripts.split(css_divider)
#         if contents[-2] != css_tag:
#             contents = contents[:-1] + [css_tag] + [contents[-1]]
#         new_contents = css_divider.join(contents)
#     with open(exp_file, 'w') as expw:
#         expw.write(new_contents)
# 
# def make_task(varname):
#     '''Replace PsiTurk's example task.js with the standard Speriment task.js,
#     with the JSON object variable name inserted.'''
#     with open('./static/js/task.js', 'w') as task:
#         task.write('''$(document).ready(function(){
#     var mySperiment = ''' + varname + ''';
#     var psiturk = PsiTurk(uniqueId, adServerLoc);
#     psiturk.finishInstructions();
#     var speriment = new Experiment(mySperiment, condition, counterbalance, psiturk);
#     speriment.start();
# });''')
# 
# class IDGenerator:
#     '''Creates an object to generate unique IDs for experimental components. You
#     should create exactly one per experiment so that all IDs in that experiment
#     will be distinct.
# 
#     Usage:
#     with make_experiment(IDGenerator()):
#         <experiment code>
#     '''
# 
#     def __init__(self, seed = -1):
#         '''seed: optional, an integer to start making IDs at.'''
#         self.current_id = seed
# 
#     def _current(self):
#         return self.current_id
# 
#     def _next_id(self):
#         '''Takes no arguments and returns a string, which is a new unique ID.'''
#         self.current_id += 1
#         return str(self.current_id)


# Path: speriment/components/experiment.py
from component import Component
from sample_from import SampleFrom
from speriment.compiler import ExperimentEncoder
from speriment.utils import make_exp, make_task, IDGenerator
import pkg_resources, json, jsonschema, copy

                if not all(sampler.field in fields for sampler in samplers):
                    for sampler in samplers:
                        if sampler.field not in fields:
                            raise ValueError('''Attempt to sample {} field from {}, which is not among its fields'''.format(sampler.field, bank_name))

    def _validate_json(self, json_object):
        contents = pkg_resources.resource_string(__name__, 'sperimentschema.json')
        schema = json.loads(contents)
        jsonschema.validate(json_object, schema)

    def to_JSON(self):
        SampleFrom._compile_time_generators = copy.deepcopy(SampleFrom._id_generators)
        return json.dumps(self, indent = 4, cls = ExperimentEncoder)

    def to_file(self, filename, varname):
        '''validates the structure of the experiment and writes it as a JSON
        object in a JavaScript file.'''
        json_experiment = self.to_JSON()
        self._validate_json(json_experiment)
        to_write = 'var ' + varname + ' = ' + json_experiment
        with open(filename, 'w') as f:
            f.write(to_write)

    def install(self, experiment_name):
        '''validates the structure of the experiment, writes it as a JSON object
        in a JavaScript file, and gives PsiTurk access to Speriment and the JSON
        object.'''
        filename = experiment_name + '.js'
        varname = experiment_name
        self.to_file('./static/js/' + filename, varname)

        make_exp(filename)