import os
import codecs
import csv
import sys

def guesser(experiments_wordlist,control_file):
    """Makes guessing experiments. If no foil column is provided in experiments_wordlist,
       foils will be randomly chosen from all the available forms
       save the form being tested

       experiments_wordlist is the file written by the balanced_exps function.
       the control file is a csv file with two columns that look like this:

       media_source     |a link to the source of the media files (e.g. https://bonniemclean.net/videos)
       media_type       |the type (file ending) for the media files, available values are 'mp3' or 'mp4'
       muted_vids       |whether or not videos should be muted, available values are 'y' or 'n'
       headphone_check  |whether to include a headphone check ('y'/'n')
       instructions_html|the name of the instructions_html file, if not writing your own html_instructions, put 'default' here
       exitques_html    |the name of the exist questions html file, if not writing your own html exit questions, put 'default' here
       no_practiceq     |the number of practice questions (e.g 2)"""

    # read in the information from the control file
    control={}
    with open(control_file,'r',encoding='UTF-8') as infile:
        reader=csv.reader(infile)
        for row in reader:
            key=row[0]
            value=row[1]
            control[key]=value
    try:
        no_practiceq=int(control['n_practiceq'])
        media_source=control['media_source']
        media_type=control['media_type']
        muted_vids=control['muted_vids']
        instructions_html=control['instructions_html']
        exitques_html=control['exitques_html']
        headphone_check=control['headphone_check']
    except KeyError:
        print('Your control file is not formatted correctly. See help(guesser) for information on how to format it.')
    if instructions_html=='default':
        instructions_html='guesses_instructions_'+media_type+'.html'
    if exitques_html=='default':
        exitques_html='guesses_exitques.html'

    if media_type!='mp3' and media_type!='mp4':
        print('Please enter a valid media type. Valid media types are mp3 or mp4.')
        return
    
    # make a dictionary to store the experiments
    experiments={}

    # make a list of all the words here in the case that you are just
    # using simple foils
    simple_foils=[]
    
    # read in the experiments
    with open(experiments_wordlist,'r',encoding='UTF-8') as infile:
        reader=csv.DictReader(infile)
        for row in reader:
            experiment=row['experiment']
            if experiment not in experiments.keys():
                experiments[experiment]=[]
            form=row['form']
            meanings=row['meaning'].upper().split('|')
            try:
                foils=row['foils'].split('|')
            except KeyError:
                if form not in simple_foils:
                    simple_foils.append(form)
                foils='simple'
            experiments[experiment].append([form,foils,meanings])
    infile.close()

    # in the case where you have simple foils, figure out what the
    # foil list for each word is

    for exp in experiments:
        wordlist=experiments[exp]
        for i in range(len(wordlist)):
            form=wordlist[i][0]
            foils=wordlist[i][1]
            if foils=='simple':
                true_foils=list(simple_foils)
                #print(true_foils)
               # print(form)
                true_foils.remove(form)
                experiments[exp][i][1]=true_foils

    # get together the code for the guessing experiments
    
    intro_code=[]
    odd_trial=[]
    even_trial=[]
    outro_code=[]
    here = os.path.dirname(os.path.abspath(__file__))
    if media_type=='mp4':
        template=codecs.open(os.path.join(here,'templates','guesses_mp4.html'),'r','utf-8')
    else:
        template=codecs.open(os.path.join(here,'templates','guesses_mp3.html'),'r','utf-8')
    
    section=1
    for line in template:
        if section==1:
            # intro code
            intro_code.append(line)
            if '<!---TRIAL START!---->' in line:
                section+=1
        elif section==2:
            # real test items
            odd_trial.append(line)
            if '<!---EVEN TRIAL!---->' in line:
                section+=1
        elif section==3:
            even_trial.append(line)
            if '<!---TRIAL END!---->' in line:
                section+=1   
        else:
            # outro code
            myline=line
            if "$('#participate').click(showAudioTest);" in line:
                if headphone_check=='n':
                    myline=line.replace('showAudioTest','easystart')
            outro_code.append(myline)

    # add instructions to the intro code

    instructions=codecs.open(os.path.join(here,'templates',instructions_html),'r','utf8')
    instructions_l=[]
    for line in instructions:
        instructions_l.append(line)

    # split intro code into two by line INSTRUCTIONS
    for i in range(len(intro_code)):
        if 'INSTRUCTIONS' in intro_code[i]:
            index=i
    intro_code_1=intro_code[:index]
    intro_code_2=intro_code[index+1:]
    intro_code=intro_code_1+instructions_l+intro_code_2
    

    # add exit quest to the outro code
    exitques=codecs.open(os.path.join(here,'templates',exitques_html),'r','utf-8')
    exit_l=[]
    for line in exitques:
        exit_l.append(line)

    # split outro code into two by line EXIT QUESTIONS
    for i in range(len(outro_code)):
        if 'OUTRO_QUESTIONS' in outro_code[i]:
            index=i

    outro_code_1=outro_code[:index]
    outro_code_2=outro_code[index+1:]
    outro_code=outro_code_1+exit_l+outro_code_2

    
    # make the code for each experiment, and store that in all_experiments
    all_experiments=[]
    for exp in experiments:
        code=[]

        # first the intro code
        for line in intro_code:
            if 'experimentX.php' in line:
                code.append(line.replace('X',exp))
            else:
                code.append(line)

        # then the trial code
        trials=experiments[exp]
        n=1

        # keep track of all the foils, and all the trans in order, as you need to
        # put these in the outro code at the end

        allfoils=[]
        alltrans=[]
        
        for trial in trials:
            foils=trial[1]
            trans=trial[2]
            for i in range(len(foils)):
                foils[i]=media_source+'/'+foils[i]+'.'+media_type

            allfoils.append(foils)
            alltrans.append(trans)

            # I have different odd and even trials because in the even trials the answer is A,
            # in the odd trials the answer is B.
          
            if n%2!=0:
                trial_code=odd_trial
            else:
                trial_code=even_trial
            for line in trial_code:
                if '<div id="trial1" class="trialDiv">' in line:
                    myline=line.replace('trial1','trial'+str(n))
                elif "id='trans1'" in line:
                    myline=line.replace('trans1','trans'+str(n))
                elif 'name="chosentrans1"' in line:
                    myline=line.replace('chosentrans1','chosentrans'+str(n))
                elif "id='realplayer-1'" in line:
                    myline=line.replace('realplayer-1','realplayer-'+str(n))
                    if media_type=='mp4' and muted_vids=='n':
                        myline=myline.replace('muted','')
                elif "id='foilplayer-1'" in line:
                    myline=line.replace('foilplayer-1','foilplayer-'+str(n))
                    if media_type=='mp4' and muted_vids=='n':
                        myline=myline.replace('muted','')
                elif 'id="chosenfoil1"' in line:
                    myline=line.replace('chosenfoil1','chosenfoil'+str(n))                    
                elif "ANSWER_MEDIA" in line:
                    word=trial[0]
                    myline=line.replace('ANSWER_MEDIA',media_source+'/'+word+'.'+media_type)
                elif 'options1' in line:
                    myline=line.replace('options1','options'+str(n))
                elif 'q1' in line:
                    myline=line.replace('q1','q'+str(n))
                elif 'ques1' in line:
                    myline=line.replace('ques1','ques'+str(n))
                elif 'reactionTime1' in line:
                    myline=line.replace('reactionTime1','reactionTime'+str(n))
                    myline=myline.replace('rt1','rt'+str(n))
                else:
                    myline=line
                code.append(myline)
            n+=1

        # then finally the outro code
        for line in outro_code:
            if 'allfoils=[[],[]]' in line:
                begin='[['
                for i in range(len(allfoils)):
                    items=allfoils[i]
                    for z in range(len(items)):
                        if z==len(items)-1:
                            if i==len(allfoils)-1:
                                begin+='"'+items[z]+'"]]'
                            else:
                                begin+='"'+items[z]+'"],['
                        else:
                            begin+='"'+items[z]+'",'
                    
                myline=line.replace('[[],[]]',begin)
                    
            elif 'alltrans=[[],[]]' in line:
                sub='[['
                for i in range(len(alltrans)):
                    items=alltrans[i]
                    for z in range(len(items)):
                        if z==len(items)-1:
                            if i==len(alltrans)-1:
                               sub+='"'+items[z]+'"]]'
                            else:
                                sub+='"'+items[z]+'"],['
                        else:
                            sub+='"'+items[z]+'",'
                myline=line.replace('[[],[]]',sub)

            elif 'i<2' in line:
                myline=line.replace('2',str(n-1))
            elif 'var shuffled = shuffle([3,4,5,6]);' in line:
                num_items=n-1
                string=''
                for i in range(num_items-no_practiceq):
                    if i==0:
                        string+=str(i+no_practiceq+1)
                    else:
                        string+=','+str(i+no_practiceq+1)
                myline=line.replace('3,4,5,6',string)
            elif 'var trialOrder =[1,2].concat(shuffled);' in line:
                string=''
                for i in range(no_practiceq):
                    if i==0:
                        string+=str(i+1)
                    else:
                        string+=','+str(i+1)
                myline=line.replace('1,2',string)
                if no_practiceq==0:
                    myline='var trialOrder=shuffled;'
            elif 'var nTrials=6' in line:
                myline=line.replace('6',str(num_items))   
            else:
                myline=line
            code.append(myline)

        # get rid of the stuff ending the script and form
        code=code[:-2]        
    
        # add the inner HTML lines

        trans_rep="document.getElementById('transX').innerHTML='One of them means '+trans_choices[X]"
        ques_rep="document.getElementById('quesX').innerHTML='Which one do you think means '+trans_choices[X]+'?'"
        foil_rep="document.getElementById('foilplayer-X').src=foil_choices[X]"
        for z in range(num_items):
            trans=trans_rep.replace('transX','trans'+str(z+1))
            trans=trans.replace('X',str(z))
            ques=ques_rep.replace('quesX','ques'+str(z+1))
            ques=ques.replace('X',str(z))
            foil=foil_rep.replace('foilplayer-X','foilplayer-'+str(z+1))
            foil=foil.replace('X',str(z))
            code.append(trans)
            code.append(ques)
            code.append(foil)

        # add back the end of the script and form
        code.append('</script>')
        code.append('</form>')
        all_experiments.append(code)


    # check what questions are in the exit survey
    exit_vars=[]
    for line in exitques:
        if 'name=' in line:
            split=line.split('name=')[1]
            try:
                var=split.split('"')[1]
            except IndexError:
                var=split.split("'")[1]
            if var not in exit_vars:
                exit_vars.append(var)
        

    # write all the experiments
    n=1
    path=os.getcwd()+'\\experiments\\'
    if not os.path.exists(path):
        os.mkdir(path)
    
    for exp in all_experiments:
        name='experiment'+str(n)+'.html'
        # write the experiment
        with open(path+name,'w') as outfile:
            for line in exp:
                outfile.write('%s\n'%line.strip('\n'))
        outfile.close()

        # write the php
        php=[]
        php_template=codecs.open(os.path.join(here,'templates','php_temp.php'),'r','utf-8')
        
        for line in php_template:
            if 'data.csv' in line:
                newline=line.replace('data','experiment'+str(n))
            else:
                newline=line
            php.append(newline)

        php_file='experiment'+str(n)+'.php'
        with open(path+php_file,'w') as outfile:
            for line in php:
                outfile.write('%s\n'%line.strip('\n'))
        outfile.close()

        # write the csv file to store responses
        csv_file='experiment'+str(n)+'.csv'
        with open(path+csv_file,'w',newline='') as outfile:
            writer=csv.writer(outfile)
            n_items=len(experiments[str(n)])
            header=[]
            for i in range(n_items):
                header.append('trans'+str(i+1))
                header.append('foil'+str(i+1))
                header.append('answer'+str(i+1))
                header.append('ReactionTime'+str(i+1))
            for var in exit_vars:
                header.append(var)
                print(var)
            writer.writerow(header)
        outfile.close()
        n+=1
