#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
 Created by <NAME>                                                       
 25/06/2010                                                                       
 The package contains functions to analyse all sentence of a utterance            
 Functions:                                 
    dispatching : to distribute the sentence          
    separ_sentence : to process the beginning of the sentence 
    exclama_sentence : to process exclamatively sentence                     
    w_quest_where : to process many different type of where question      
    w_quest_class : to process what question about classification   
    w_quest_what  : to process many different type of what question                 
    w_quest_quant : to process many different type of how question
    w_quest_how : to process many different type of how question
    w_quest_which : to process which question                    
    stc_start_subsentence : to process the subsentence at the beginning of the sentence                           
    w_quest_whose : to process many different type of whose question   
    w_quest_whom : to process whom question
    y_n_ques : to process the yes or no question from of a sentence                 
    other_sentence : to process the other from of a sentence                        
    sentences_analyzer : is the basic function of parsing                         
"""
from dialogs.sentence import *
from dialogs.sentence_types import *
from dialogs.resources_manager import ResourcePool
from . import analyse_nominal_group
from . import analyse_nominal_structure
from . import analyse_verb
from . import analyse_verbal_structure
from . import other_functions
from . import preprocessing


def dispatching(sentence):
    """
    distributes the sentence according to:                             
    Their functionality and their type                                               
    Input=sentence, beginning sentence list          Output=class Sentence           
    """

    if len(sentence) > 0:

        #For ending dialogue
        if sentence[0].endswith('bye'):
            return [Sentence(END, '', [], [])]

        #When others
        for x in ResourcePool().sentence_starts:
            #If we find a knowing case
            if sentence[0] == x[0]:


                #For
                if x[1] == '1':
                    return [Sentence(START, '', [], [])]

                #It's a w_question or subsentence
                if x[1] == '2':

                    #If there is which or no nominal group it is a question
                    if sentence[0] != 'which' and analyse_nominal_group.find_sn_pos(sentence, 1) != []:
                        #Here we have the condition of the subsentences
                        return [stc_start_subsentence(sentence)]

                    #For 'when'
                    if x[2] == '1':
                        #If we remove the first word => it becomes like y_n_question
                        return [y_n_ques(W_QUESTION, 'date', sentence[1:])]

                    #For 'where'
                    elif x[2] == '2':
                        return [w_quest_where(W_QUESTION, 'place', sentence)]

                    #For 'what'
                    elif x[2] == '3':
                        #Here we have to use a specific processing for 'type' and 'kind'
                        if sentence[1] == 'type' or sentence[1] == 'kind':
                            #We start by processing the end of the sentence like a y_n_question
                            return [w_quest_class(sentence)]

                        #For other type of 'what' question
                        else:
                            return [w_quest_what(W_QUESTION, sentence)]

                    #For 'how'
                    elif x[2] == '4':

                        if sentence[1] == 'many' or sentence[1] == 'much':
                            return [w_quest_quant(W_QUESTION, 'quantity', sentence)]

                        elif sentence[1] == 'about':
                            #We replace 'about' by 'is' to have a y_n_question
                            sentence[1] = 'is'
                            return [y_n_ques(W_QUESTION, 'invitation', sentence[1:])]

                        #For other type of 'how' question
                        else:
                            return [w_quest_how(W_QUESTION, sentence)]

                    #For 'why'
                    elif x[2] == '5':
                        return [y_n_ques(W_QUESTION, 'reason', sentence[1:])]

                    #For 'whose'
                    elif x[2] == '6':
                        return [w_quest_whose(W_QUESTION, 'owner', sentence)]

                    #For 'who'
                    elif x[2] == '7':
                        return [y_n_ques(W_QUESTION, 'people', sentence[1:])]

                    #For 'which'
                    elif x[2] == '8':
                        return [w_quest_which(W_QUESTION, 'choice', sentence[1:])]

                    #For 'to whom'
                    elif x[2] == '9':
                        return [w_quest_whom(W_QUESTION, 'people', sentence[1:])]

                #It's a y_n_question
                elif x[1] == '3':
                    return [y_n_ques(YES_NO_QUESTION, '', sentence)]

                #It's a conditional sentence
                elif x[1] == '4':
                    return [stc_start_subsentence(sentence)]

                #Agree
                elif x[1] == '5':
                    return separ_sentence(sentence, AGREEMENT)

                #Disagree
                elif x[1] == '6':
                    return separ_sentence(sentence, DISAGREEMENT)

                #Gratulation
                elif x[1] == '7':
                    return separ_sentence(sentence, GRATULATION)

                #Interjunction
                elif x[1] == '8':
                    return [exclama_sentence(sentence)]

        #For exclamatively
        if sentence[len(sentence) - 1] == '!':
            return [exclama_sentence(sentence)]

        #It's a statement or an imperative sentence
        return [other_sentence('', '', sentence)]

    #Default case
    return []


def separ_sentence(sentence, data_type):
    """
    process the beginning of the sentence                       
    Input=the sentence                                   Output=class Sentence   
    """

    #If we have good followed by another word it can be start
    if data_type == AGREEMENT and len(sentence) > 1 and (
                sentence[1] == 'morning' or sentence[1] == 'evening' or sentence[1] == 'afternoon'):
        sentences = [Sentence(START, '', [], [])]
    else:
        #init
        sentences = [Sentence(data_type, '', [], [])]

    for i in sentence:
        if i == ';':
            #We put the first sentence in the aim
            sentences[0].aim = " ".join(sentence[:sentence.index(i)]).rstrip('; ') + '.'
            sentence = sentence[sentence.index(i) + 1:]
            #We process the end of the sentence as a complete sentence
            sentence = preprocessing.process_and_beginning_sentence(sentence)
            sentences = sentences + dispatching(sentence)
            break
        else:
            #In this case, it is the end of the sentence
            sentences[0].aim = " ".join(sentence).rstrip('. ') + '.'

    return sentences


def exclama_sentence(sentence):
    """
    process exclamatively sentence                       
    Input=the sentence                                   Output=class Sentence   
    """

    for i in ResourcePool().sentence_starts:
        if i[0] == sentence[0]:
            if i[1] == '0':
                analysis = Sentence(INTERJECTION, '', [], [])
                #We recover the subject
                sentence = analyse_nominal_structure.recover_ns(sentence, analysis, 1)
                return analysis
            elif i[1] == '2':
                #It is an exclamation sentence
                analysis = Sentence(EXCLAMATION, '', [], [])
                #We recover the subject
                sentence = analyse_nominal_structure.recover_ns(sentence, analysis, 0)
                return analysis

    #If we have an imperative it can be forced
    analysis = other_sentence(INTERJECTION, '', sentence)
    if analysis.data_type == INTERJECTION and not analysis.sv:
        pass
    else:
        analysis.data_type = IMPERATIVE
    return analysis


def w_quest_where(type, request, stc):
    """
    process many different type of where question                       
    Input=type and requesting of sentence, the sentence      Output=class Sentence   
    """

    #If there is 'form' at the end => question about the origin
    if stc[len(stc) - 1] == 'from' or (stc[len(stc) - 1] == '?' and stc[len(stc) - 2] == 'from'):
        #If we remove the first word => it becomes like y_n_question
        return y_n_ques(type, 'origin', stc[1:])
    else:
        #If we remove the first word => it becomes like y_n_question
        return y_n_ques(type, request, stc[1:])


def w_quest_class(sentence):
    """
    process what question about classification                       
    Input=sentence                                       Output=class Sentence   
    """

    analysis = y_n_ques(W_QUESTION, 'classification' + '+' + sentence[4], sentence[5:])
    if analysis.sn:
        #The direct object must be empty
        if analysis.sv[0].d_obj:
            analysis.sv[0].i_cmpl = analysis.sv[0].i_cmpl + [IndirectComplement([], analysis.sv[0].d_obj)]
            analysis.sv[0].d_obj = []
    return analysis


def w_quest_what(type, sentence):
    """
    process many different type of what question                        
    Input=type of sentence, the sentence and position of subject                      
    Output=class Sentence                                                            
    """

    aux_list = other_functions.recover_aux_list()
    if sentence[1] in aux_list:

        #We start with a processing with the function of y_n_question's case
        analysis = y_n_ques(type, 'thing', sentence[1:])

        vg = analysis.sv[0]
        #The case when we have 'happen'
        if analysis.sv[0].vrb_main[0].endswith('happen'):
            analysis.aim = 'situation'

        #The case when we have 'think'
        elif analysis.sv[0].vrb_main[0].endswith('think+of') or analysis.sv[0].vrb_main[0].endswith('think+about'):
            analysis.aim = 'opinion'

        #The case when we have 'like' + conditional
        elif analysis.sv[0].vrb_main[0].endswith('like') and not (analysis.sv[0].vrb_tense.endswith('conditional')):
            analysis.aim = 'description'

        #The case when we have 'do' + ing form
        elif vg.vrb_main[0].endswith('do') and \
                        vg.i_cmpl != [] and \
                        vg.i_cmpl[0].gn[0].adj != [] and \
                        vg.i_cmpl[0].gn[0].adj[0][0].endswith('ing'):
            analysis.aim = 'explication'

    #There is a noun before the auxiliary
    else:
        #We will use the same code as the which questions
        sentence = ['the'] + sentence[1:]
        #We need to have a nominal group at the beginning
        analysis = w_quest_which(type, 'thing', sentence)
    return analysis


def w_quest_quant(type, request, sentence):
    """
    process many different type of quantity question                    
    Input=type and requesting of sentence, the sentence and beginning sentence list  
    Output=class Sentence                                                            
    """

    for j in ResourcePool().sentence_starts:
        if sentence[2] == j[0]:
            if j[1] == '3':
                #This case is the same with y_n_question
                return y_n_ques(type, request, sentence[2:])

    analysis = y_n_ques(type, request, sentence[3:])

    #There is not sn in the sentence
    if not analysis.sn:
        analysis.sn = [NominalGroup(['a'], [sentence[2]], [], [], [])]

    else:
        #There is not direct object in the sentence
        analysis.sv[0].d_obj = [NominalGroup(['a'], [sentence[2]], [], [], [])]

    return analysis


def w_quest_how(type, sentence):
    """
    process many different type of how question                         
    Input=type of sentence, the sentence      Output=class Sentence                  
    """

    aux_list = other_functions.recover_aux_list()
    if sentence[1] in aux_list:
        analysis = y_n_ques(type, 'manner', sentence[1:])

        #The case when we have 'do' + ing form
        if analysis.sv[0].vrb_main[0].endswith('like'):
            analysis.aim = 'opinion'
        return analysis

    analysis = y_n_ques(type, sentence[1], sentence[2:])
    return analysis


def w_quest_which(type, request, sentence):
    """
    process which question                       
    Input=type of sentence, the sentence      Output=class Sentence                  
    """

    #We start by finding the nominal group
    gr = preprocessing.determination_nominal_group(sentence, 0, 'of')

    #If the nominal group contain just 2 elements
    if len(gr) == 2:
        return y_n_ques(type, sentence[1], sentence[2:])
    else:
        #After the first gr if there is no nominal group
        if not analyse_nominal_group.find_sn_pos(sentence, len(gr)):
            for i in ResourcePool().sentence_starts:
                #If just after we have an a auxiliary
                if sentence[len(gr)] == i[0] and i[1] == '3':
                    #With subject => it is a yes or no question form
                    if analyse_nominal_group.find_sn_pos(sentence, len(gr) + 1):
                        analysis = y_n_ques(type, request, sentence[len(gr):])
                        nominal_gr = other_sentence(type, request, gr)
                        analysis.sv[0].d_obj = nominal_gr.sn
                        return analysis
                #Else it is like a statement
            return other_sentence(type, request, sentence)

        #Else if not, the first nominal group is the subject
        else:
            analysis = other_sentence(type, request, sentence[len(gr):])
            nominal_gr = other_sentence(type, request, gr)
            analysis.sv[0].d_obj = nominal_gr.sn
            return analysis


def stc_start_subsentence(sentence):
    """
    process the subsentence at the beginning of the sentence
    Input=sentence                                          Output=class Sentence    
    """
    #We have to add punctuation if there is not
    if sentence[len(sentence) - 1] != '.' and sentence[len(sentence) - 1] != '?' and sentence[len(sentence) - 1] != '!':
        sentence = sentence + ['.']

    #We recover the subsentence
    for i in sentence:
        if i == ';' or i == '.' or i == '?' or i == '!':
            subsentence = sentence[1:sentence.index(i)]

            #We perform the 2 processing
            if sentence.index(i) != len(sentence) - 1:
                analysis = other_sentence(STATEMENT, '', sentence[sentence.index(i) + 1:])
            else:
                vg = VerbalGroup([], [], '', [], [], [], [], VerbalGroup.affirmative, [])
                analysis = Sentence('', '', [], [vg])
            break

    #We process the subsentence 
    analysis.sv[0].vrb_sub_sentence = analysis.sv[0].vrb_sub_sentence + dispatching(subsentence)
    if analysis.sv[0].vrb_sub_sentence:
        analysis.sv[0].vrb_sub_sentence[len(analysis.sv[0].vrb_sub_sentence) - 1].data_type = SUBSENTENCE + '+' + \
                                                                                              analysis.sv[
                                                                                                  0].vrb_sub_sentence[
                                                                                                  len(analysis.sv[
                                                                                                      0].vrb_sub_sentence) - 1].data_type
        if sentence[0][0] == ':':
            analysis.sv[0].vrb_sub_sentence[len(analysis.sv[0].vrb_sub_sentence) - 1].aim = sentence[0][1:]
        else:
            analysis.sv[0].vrb_sub_sentence[len(analysis.sv[0].vrb_sub_sentence) - 1].aim = sentence[0]

    return analysis


def w_quest_whose(type, request, sentence):
    """
    process many different type of whose question                       
    Input=type and requesting of sentence and the sentence                           
    Output=class Sentence                                                           
    """

    #init
    vg = VerbalGroup(['be'], [], '', [], [], [], [], VerbalGroup.affirmative, [])
    analysis = Sentence(type, request, [], [])


    #We replace 'whose' by 'that' to have a nominal group
    sentence[0] = 'that'

    #We recover the subject
    sentence = analyse_nominal_structure.recover_ns(sentence, analysis, 0)

    if sentence[1] == 'not':
        vg.state = 'negative'

    analysis.sv = [vg]
    return analysis


def w_quest_whom(type, request, sentence):
    """
    process whom question                                            
    Input=type and requesting of sentence and the sentence
    Output=class Sentence                                                            
    """

    #It is the same with yes or no question
    analysis = y_n_ques(type, request, sentence)

    #We have to add 'to' to the verb
    analysis.sv[0].vrb_main[0] += '+to'

    return analysis


def y_n_ques(type, request, sentence):
    """
    process the yes or no question from of a sentence
    Input=type and requesting of sentence and the sentence                           
    Output=class Sentence                                                            
    """

    #init
    vg = VerbalGroup([], [], '', [], [], [], [], VerbalGroup.affirmative, [])
    analysis = Sentence(type, request, [], [])
    modal = []
    stc = sentence

    #We start with determination of probably second verb in subsentence
    sentence = other_functions.find_scd_verb_sub(sentence)

    #We have to add punctuation if there is not
    if sentence == [] or sentence[0] == '.' or sentence[0] == '?' or sentence[0] == '!':
        #We have probably the aim as an adverb
        analyse_verbal_structure.find_adv([request], vg)
        analysis.aim = 'thing'
        analysis.sv = [vg]
        return analysis

    #We recover the auxiliary 
    aux = sentence[0]

    #We have to know if there is a modal
    if aux in ResourcePool().modal:
        modal = aux

    #If we have a negative form
    if sentence[1] == 'not':
        vg.state = VerbalGroup.negative
        #We remove 'not'
        sentence = sentence[:1] + sentence[2:]

    #Wrong is a noun but not followed by the determinant
    if sentence[1] == 'wrong' and request == 'thing':
        analysis.sn = [NominalGroup([], [], ['wrong'], [], [])]
        sentence = [sentence[0]] + sentence[2:]

    #In this case we have an imperative sentence
    elif analyse_nominal_group.find_sn_pos(sentence, 1) == [] and type != W_QUESTION:
        #We have to reput the 'not'
        if vg.state == VerbalGroup.negative:
            sentence = sentence[:1] + ['not'] + sentence[1:]
        return other_sentence(type, request, sentence)

    #We delete the auxiliary
    sentence = sentence[1:]

    #We have to separate the case using these, this or there
    if sentence[0] in ResourcePool().demonstrative_det and analyse_verb.infinitive([aux], 'present simple') == ['be']:
        #If we have a verb or an adverb just after (if not, we have a noun)
        if sentence[0].endswith('ed') or sentence[0].endswith('ing') or sentence[0].endswith('ly') or sentence[
            0] in ResourcePool().adverbs:
            #We recover this information and remove it
            analysis.sn = [NominalGroup([sentence[0]], [], [], [], [])]
            if sentence[0] == 'there' and aux == 'are':
                analysis.sn[0]._quantifier = 'SOME'
            sentence = sentence[1:]

    if not analysis.sn:
        #We recover the subject
        sentence = analyse_nominal_structure.recover_ns(sentence, analysis, 0)

    if aux == 'do' and not analyse_verbal_structure.can_be_imperative(sentence):
        return other_sentence('', '', stc)

    #If there is one element => it is an auxiliary => verb 'be'
    if len(sentence) == 0:
        vg.vrb_tense = analyse_verb.find_tense_statement(aux)
        vg.vrb_main = ['be']
    else:
        sentence = analyse_verbal_structure.delete_unusable_word(sentence)
        sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)
        vg.vrb_tense = analyse_verb.find_tense_question(sentence, aux)

        #We process the verb
        verb = analyse_verb.find_verb_question(sentence, aux, vg.vrb_tense)
        verb_main = analyse_verb.return_verb(sentence, verb, vg.vrb_tense)
        vg.vrb_main = [other_functions.convert_to_string(verb_main)]

        #We delete the verb if the aux is not the verb 'be'
        if vg.vrb_main != ['be']:
            sentence = sentence[sentence.index(verb[0]) + len(verb_main):]
        elif sentence[0] == 'be':
            sentence = sentence[1:]

        #Here we have special processing for different cases
        if sentence:
            #For 'what' descrition case
            if sentence[0] == 'like' and aux != 'would':
                vg.vrb_main = ['like']
                sentence = sentence[1:]

            #For 'how' questions with often
            elif sentence[0].endswith('ing') and not (sentence[0].endswith('thing')):
                vg.vrb_main[0] = vg.vrb_main[0] + '+' + sentence[0]
                sentence = sentence[1:]

        #We recover the conjunctive subsentence
        sentence = analyse_verbal_structure.process_conjunctive_sub(sentence, vg)

        #It verifies if there is a secondary verb
        sec_vrb = analyse_verbal_structure.find_scd_vrb(sentence)
        if sec_vrb:
            sentence = analyse_verbal_structure.process_scd_sentence(sentence, vg, sec_vrb)

        #We recover the subsentence
        sentence = analyse_verbal_structure.process_subsentence(sentence, vg)

        #Process relative changes
        sentence = analyse_verbal_structure.correct_i_compl(sentence, vg.vrb_main[0])

        sentence = analyse_verbal_structure.process_compare(sentence, vg)

        sentence = analyse_nominal_group.find_plural(sentence)
        #We recover the direct, indirect complement and the adverbial
        sentence = analyse_verbal_structure.recover_obj_iobj(sentence, vg)

        #We have to take off adverbs form the sentence
        sentence = analyse_verbal_structure.find_adv(sentence, vg)

    #We perform the processing with the modal
    if modal:
        vg.vrb_main = [modal + '+' + vg.vrb_main[0]]

    #If there is a forgotten
    sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)

    #In case there is a state verb followed by an adjective
    sentence = analyse_verbal_structure.state_adjective(sentence, vg)

    #We have to correct the mistake of the subject
    for p in ResourcePool().demonstrative_det:
        if analysis.sn and analysis.sn[0].det == [p] and analysis.sn[0].noun == []:
            if sentence != [0] and sentence[0] == '.' and sentence[0] == '?' and sentence[0] == '!':
                if sentence[0] in ResourcePool().proposals:
                    pass
                else:
                    analysis.sn[0].noun = [sentence[0]]
                    sentence = sentence[1:]
                    sentence = analyse_verbal_structure.state_adjective(sentence, vg)

    vg = analyse_verbal_structure.DOC_to_IOC(vg)

    while len(sentence) > 1:
        stc = analyse_verbal_structure.create_nom_gr(sentence, request)
        #We recover the direct, indirect complement and the adverbial
        stc = analyse_verbal_structure.recover_obj_iobj(stc, vg)
        if stc == sentence:
            #We leave the loop
            break
        else:
            sentence = stc

    vg = analyse_verbal_structure.refine_indirect_complement(vg)
    vg = analyse_verbal_structure.refine_subsentence(vg)
    vg = analyse_verbal_structure.DOC_to_IOC(vg)

    analysis.sv = [vg]
    return analysis


def other_sentence(type, request, sentence):
    """
    process the other from of a sentence                                
    Input=type and requesting of sentence and the sentence                               
    Output=class Sentence                                                            
    """

    #init
    vg = VerbalGroup([], [], '', [], [], [], [], VerbalGroup.affirmative, [])
    analysis = Sentence(type, request, [], [])
    modal = []

    if not sentence:
        return []

    #We have to add punctuation if there is not
    if sentence[len(sentence) - 1] not in ['.', '?', '!']:
        sentence = sentence + ['.']

    #We start with determination of probably second verb in subsentence
    sentence = other_functions.find_scd_verb_sub(sentence)

    #We search the subject
    sbj = analyse_nominal_group.find_sn_pos(sentence, 0)

    if sbj != [] or type == RELATIVE:
        #If we haven't a data type => it is a statement
        if type == '':
            analysis.data_type = STATEMENT


        #We have to separate the case using these, this or there
        if sentence[0] in ResourcePool().demonstrative_det and analyse_verb.infinitive([sentence[1]],
                                                                                       'present simple') == ['be']:
            #We recover this information and remove it
            analysis.sn = [NominalGroup([sentence[0]], [], [], [], [])]
            if sentence[0] == 'there' and sentence[1] == 'are':
                analysis.sn[0]._quantifier = 'SOME'
            sentence = sentence[1:]

        if not analysis.sn:
            #We recover the subject
            sentence = analyse_nominal_structure.recover_ns(sentence, analysis, 0)

        #End of the sentence? -> nominal sentence
        if sentence == [] or sentence[0] in ['.', '!', '?']:
            analysis.sv = []
            return analysis

        #We have to know if there is a modal
        if sentence[0] in ResourcePool().modal:
            modal = sentence[0]
            if modal == 'can' or modal == 'must' or modal == 'shall' or modal == 'may':
                sentence = sentence[1:]

        #We must take into account all possible cases to recover the sentence's tense
        if len(sentence) > 1 and sentence[1] == 'not':
            vg.state = VerbalGroup.negative

            #Before the negative form we have an auxiliary for the negation
            if sentence[0] == 'do' or sentence[0] == 'does' or sentence[0] == 'did':
                vg.vrb_tense = analyse_verb.find_tense_statement([sentence[0]])
                sentence = sentence[2:]
                sentence = analyse_verbal_structure.delete_unusable_word(sentence)
                sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)

            #There is a modal
            elif modal:
                sentence = [sentence[0]] + sentence[2:]
                sentence = analyse_verbal_structure.delete_unusable_word(sentence)
                sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)
                vg.vrb_tense = analyse_verb.find_tense_statement(sentence)

            else:
                #We remove 'not' and find the tense
                sentence = sentence[:1] + sentence[2:]
                sentence = analyse_verbal_structure.delete_unusable_word(sentence)
                sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)
                vg.vrb_tense = analyse_verb.find_tense_statement(sentence)

        #For the affirmative processing
        else:
            if sentence[0] == 'not':
                vg.state = VerbalGroup.negative
                sentence = sentence[1:]

            sentence = analyse_verbal_structure.delete_unusable_word(sentence)
            sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)
            vg.vrb_tense = analyse_verb.find_tense_statement(sentence)

        verb = analyse_verb.find_verb_statement(sentence, vg.vrb_tense)
        verb_main = analyse_verb.return_verb(sentence, verb, vg.vrb_tense)
        vg.vrb_main = [other_functions.convert_to_string(verb_main)]

        #We delete the verb
        sentence = sentence[sentence.index(verb[0]) + len(verb_main):]

        #We perform the processing with the modal
        if modal:
            vg.vrb_main = [modal + '+' + vg.vrb_main[0]]

    #This is a imperative form
    else:
        #re-init
        analysis.data_type = IMPERATIVE
        vg.vrb_tense = 'present simple'

        if sentence[0] in ResourcePool().proposals:
            sentence = ['.'] + sentence

        #Negative form
        if sentence[1] == 'not':
            sentence = sentence[sentence.index('not') + 1:]
            sentence = analyse_verbal_structure.delete_unusable_word(sentence)
            sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)
            vg.state = VerbalGroup.negative
        else:
            sentence = analyse_verbal_structure.delete_unusable_word(sentence)
            sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)

        #We process the verb
        verb = [sentence[0]]
        verb_main = analyse_verb.return_verb(sentence, verb, vg.vrb_tense)
        vg.vrb_main = [other_functions.convert_to_string(verb_main)]

        #We delete the verb
        sentence = sentence[sentence.index(verb[0]) + len(verb_main):]

    if sentence and sentence[-1] == '?':
        analysis.data_type = YES_NO_QUESTION

    #We recover the conjunctive subsentence
    sentence = analyse_verbal_structure.process_conjunctive_sub(sentence, vg)

    #It verifies if there is a secondary verb
    sec_vrb = analyse_verbal_structure.find_scd_vrb(sentence)
    if sec_vrb:
        sentence = analyse_verbal_structure.process_scd_sentence(sentence, vg, sec_vrb)

    #We recover the subsentence
    sentence = analyse_verbal_structure.process_subsentence(sentence, vg)

    if sentence != [] and vg.vrb_main != []:
        #Process relative changes
        sentence = analyse_verbal_structure.correct_i_compl(sentence, vg.vrb_main[0])

    sentence = analyse_verbal_structure.process_compare(sentence, vg)

    sentence = analyse_nominal_group.find_plural(sentence)
    #We recover the direct, indirect complement and the adverbial
    sentence = analyse_verbal_structure.recover_obj_iobj(sentence, vg)

    #We have to take off abverbs form the sentence
    sentence = analyse_verbal_structure.find_adv(sentence, vg)

    #In case there is a state verb followed by an adjective
    sentence = analyse_verbal_structure.state_adjective(sentence, vg)

    #If there is a forgotten
    sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)

    vg = analyse_verbal_structure.DOC_to_IOC(vg)

    while len(sentence) > 1:
        stc = analyse_verbal_structure.create_nom_gr(sentence, request)
        #We recover the direct, indirect complement and the adverbial
        stc = analyse_verbal_structure.recover_obj_iobj(stc, vg)
        if stc == sentence:
            #We leave the loop
            break
        else:
            sentence = stc

    vg = analyse_verbal_structure.refine_indirect_complement(vg)
    vg = analyse_verbal_structure.refine_subsentence(vg)
    vg = analyse_verbal_structure.DOC_to_IOC(vg)

    analysis.sv = [vg]
    return analysis


def sentences_analyzer(sentences):
    """
    This function is the basic function of parsing
    Input=list of sentences and beginning sentence list
    Output=list of class Sentence
    """

    #init
    class_sentence_list = []
    nom_gr = []
    y = 0

    #We process all sentences of the list
    for i in sentences:
        if i:
            #We have to add punctuation if there is not
            if i[-1] not in ['.', '?', '!']:
                i = i + ['.']
            class_sentence_list = class_sentence_list + dispatching(i)

    #Add some information if there is an interjection
    for s in class_sentence_list:
        #If there is an interjection we have to take the nominal group
        if s.data_type == INTERJECTION:
            nom_gr = s.sn
            #If there is an imperative sentence, we put the nominal group of interjection in the subject
        if nom_gr != [] and s.data_type == IMPERATIVE:
            s.sn = s.sn + nom_gr

    #To simplify the interpretation, we have to perform some changes
    for k in class_sentence_list:
        #If subject is 'there', we change it by the object
        if k.sn != [] and k.sn[0].det == ['there']:
            k.sn = k.sv[0].d_obj
            k.sv[0].d_obj = []

        #If sentence is empty, we take off the verb
        if k.sv != [] and (k.sv[0].vrb_main == ['.'] or k.sv[0].vrb_main == ['?'] or k.sv[0].vrb_main == ['!']):
            k.sv[0].vrb_main = []
            if k.data_type == IMPERATIVE:
                k.data_type = STATEMENT

        #If we have imperative with verb 'see' => end
        if k.data_type == IMPERATIVE and \
                        k.sv[0].vrb_main == ['see'] and \
                        len(k.sv[0].d_obj) > 0 and \
                        k.sv[0].d_obj[0].noun == ['you']:
            k.data_type = END
            k.aim = ''
            k.sv = []
            k.sn = []

    return class_sentence_list

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
 Created by <NAME>                                                       
 25/06/2010                                                                       
 The package contains functions to analyse all sentence of a utterance            
 Functions:                                 
    dispatching : to distribute the sentence          
    separ_sentence : to process the beginning of the sentence 
    exclama_sentence : to process exclamatively sentence                     
    w_quest_where : to process many different type of where question      
    w_quest_class : to process what question about classification   
    w_quest_what  : to process many different type of what question                 
    w_quest_quant : to process many different type of how question
    w_quest_how : to process many different type of how question
    w_quest_which : to process which question                    
    stc_start_subsentence : to process the subsentence at the beginning of the sentence                           
    w_quest_whose : to process many different type of whose question   
    w_quest_whom : to process whom question
    y_n_ques : to process the yes or no question from of a sentence                 
    other_sentence : to process the other from of a sentence                        
    sentences_analyzer : is the basic function of parsing                         
"""
from dialogs.sentence import *
from dialogs.sentence_types import *
from dialogs.resources_manager import ResourcePool
from . import analyse_nominal_group
from . import analyse_nominal_structure
from . import analyse_verb
from . import analyse_verbal_structure
from . import other_functions
from . import preprocessing


def dispatching(sentence):
    """
    distributes the sentence according to:                             
    Their functionality and their type                                               
    Input=sentence, beginning sentence list          Output=class Sentence           
    """

    if len(sentence) > 0:

        #For ending dialogue
        if sentence[0].endswith('bye'):
            return [Sentence(END, '', [], [])]

        #When others
        for x in ResourcePool().sentence_starts:
            #If we find a knowing case
            if sentence[0] == x[0]:


                #For
                if x[1] == '1':
                    return [Sentence(START, '', [], [])]

                #It's a w_question or subsentence
                if x[1] == '2':

                    #If there is which or no nominal group it is a question
                    if sentence[0] != 'which' and analyse_nominal_group.find_sn_pos(sentence, 1) != []:
                        #Here we have the condition of the subsentences
                        return [stc_start_subsentence(sentence)]

                    #For 'when'
                    if x[2] == '1':
                        #If we remove the first word => it becomes like y_n_question
                        return [y_n_ques(W_QUESTION, 'date', sentence[1:])]

                    #For 'where'
                    elif x[2] == '2':
                        return [w_quest_where(W_QUESTION, 'place', sentence)]

                    #For 'what'
                    elif x[2] == '3':
                        #Here we have to use a specific processing for 'type' and 'kind'
                        if sentence[1] == 'type' or sentence[1] == 'kind':
                            #We start by processing the end of the sentence like a y_n_question
                            return [w_quest_class(sentence)]

                        #For other type of 'what' question
                        else:
                            return [w_quest_what(W_QUESTION, sentence)]

                    #For 'how'
                    elif x[2] == '4':

                        if sentence[1] == 'many' or sentence[1] == 'much':
                            return [w_quest_quant(W_QUESTION, 'quantity', sentence)]

                        elif sentence[1] == 'about':
                            #We replace 'about' by 'is' to have a y_n_question
                            sentence[1] = 'is'
                            return [y_n_ques(W_QUESTION, 'invitation', sentence[1:])]

                        #For other type of 'how' question
                        else:
                            return [w_quest_how(W_QUESTION, sentence)]

                    #For 'why'
                    elif x[2] == '5':
                        return [y_n_ques(W_QUESTION, 'reason', sentence[1:])]

                    #For 'whose'
                    elif x[2] == '6':
                        return [w_quest_whose(W_QUESTION, 'owner', sentence)]

                    #For 'who'
                    elif x[2] == '7':
                        return [y_n_ques(W_QUESTION, 'people', sentence[1:])]

                    #For 'which'
                    elif x[2] == '8':
                        return [w_quest_which(W_QUESTION, 'choice', sentence[1:])]

                    #For 'to whom'
                    elif x[2] == '9':
                        return [w_quest_whom(W_QUESTION, 'people', sentence[1:])]

                #It's a y_n_question
                elif x[1] == '3':
                    return [y_n_ques(YES_NO_QUESTION, '', sentence)]

                #It's a conditional sentence
                elif x[1] == '4':
                    return [stc_start_subsentence(sentence)]

                #Agree
                elif x[1] == '5':
                    return separ_sentence(sentence, AGREEMENT)

                #Disagree
                elif x[1] == '6':
                    return separ_sentence(sentence, DISAGREEMENT)

                #Gratulation
                elif x[1] == '7':
                    return separ_sentence(sentence, GRATULATION)

                #Interjunction
                elif x[1] == '8':
                    return [exclama_sentence(sentence)]

        #For exclamatively
        if sentence[len(sentence) - 1] == '!':
            return [exclama_sentence(sentence)]

        #It's a statement or an imperative sentence
        return [other_sentence('', '', sentence)]

    #Default case
    return []


def separ_sentence(sentence, data_type):
    """
    process the beginning of the sentence                       
    Input=the sentence                                   Output=class Sentence   
    """

    #If we have good followed by another word it can be start
    if data_type == AGREEMENT and len(sentence) > 1 and (
                sentence[1] == 'morning' or sentence[1] == 'evening' or sentence[1] == 'afternoon'):
        sentences = [Sentence(START, '', [], [])]
    else:
        #init
        sentences = [Sentence(data_type, '', [], [])]

    for i in sentence:
        if i == ';':
            #We put the first sentence in the aim
            sentences[0].aim = " ".join(sentence[:sentence.index(i)]).rstrip('; ') + '.'
            sentence = sentence[sentence.index(i) + 1:]
            #We process the end of the sentence as a complete sentence
            sentence = preprocessing.process_and_beginning_sentence(sentence)
            sentences = sentences + dispatching(sentence)
            break
        else:
            #In this case, it is the end of the sentence
            sentences[0].aim = " ".join(sentence).rstrip('. ') + '.'

    return sentences


def exclama_sentence(sentence):
    """
    process exclamatively sentence                       
    Input=the sentence                                   Output=class Sentence   
    """

    for i in ResourcePool().sentence_starts:
        if i[0] == sentence[0]:
            if i[1] == '0':
                analysis = Sentence(INTERJECTION, '', [], [])
                #We recover the subject
                sentence = analyse_nominal_structure.recover_ns(sentence, analysis, 1)
                return analysis
            elif i[1] == '2':
                #It is an exclamation sentence
                analysis = Sentence(EXCLAMATION, '', [], [])
                #We recover the subject
                sentence = analyse_nominal_structure.recover_ns(sentence, analysis, 0)
                return analysis

    #If we have an imperative it can be forced
    analysis = other_sentence(INTERJECTION, '', sentence)
    if analysis.data_type == INTERJECTION and not analysis.sv:
        pass
    else:
        analysis.data_type = IMPERATIVE
    return analysis


def w_quest_where(type, request, stc):
    """
    process many different type of where question                       
    Input=type and requesting of sentence, the sentence      Output=class Sentence   
    """

    #If there is 'form' at the end => question about the origin
    if stc[len(stc) - 1] == 'from' or (stc[len(stc) - 1] == '?' and stc[len(stc) - 2] == 'from'):
        #If we remove the first word => it becomes like y_n_question
        return y_n_ques(type, 'origin', stc[1:])
    else:
        #If we remove the first word => it becomes like y_n_question
        return y_n_ques(type, request, stc[1:])


def w_quest_class(sentence):
    """
    process what question about classification                       
    Input=sentence                                       Output=class Sentence   
    """

    analysis = y_n_ques(W_QUESTION, 'classification' + '+' + sentence[4], sentence[5:])
    if analysis.sn:
        #The direct object must be empty
        if analysis.sv[0].d_obj:
            analysis.sv[0].i_cmpl = analysis.sv[0].i_cmpl + [IndirectComplement([], analysis.sv[0].d_obj)]
            analysis.sv[0].d_obj = []
    return analysis


def w_quest_what(type, sentence):
    """
    process many different type of what question                        
    Input=type of sentence, the sentence and position of subject                      
    Output=class Sentence                                                            
    """

    aux_list = other_functions.recover_aux_list()
    if sentence[1] in aux_list:

        #We start with a processing with the function of y_n_question's case
        analysis = y_n_ques(type, 'thing', sentence[1:])

        vg = analysis.sv[0]
        #The case when we have 'happen'
        if analysis.sv[0].vrb_main[0].endswith('happen'):
            analysis.aim = 'situation'

        #The case when we have 'think'
        elif analysis.sv[0].vrb_main[0].endswith('think+of') or analysis.sv[0].vrb_main[0].endswith('think+about'):
            analysis.aim = 'opinion'

        #The case when we have 'like' + conditional
        elif analysis.sv[0].vrb_main[0].endswith('like') and not (analysis.sv[0].vrb_tense.endswith('conditional')):
            analysis.aim = 'description'

        #The case when we have 'do' + ing form
        elif vg.vrb_main[0].endswith('do') and \
                        vg.i_cmpl != [] and \
                        vg.i_cmpl[0].gn[0].adj != [] and \
                        vg.i_cmpl[0].gn[0].adj[0][0].endswith('ing'):
            analysis.aim = 'explication'

    #There is a noun before the auxiliary
    else:
        #We will use the same code as the which questions
        sentence = ['the'] + sentence[1:]
        #We need to have a nominal group at the beginning
        analysis = w_quest_which(type, 'thing', sentence)
    return analysis


def w_quest_quant(type, request, sentence):
    """
    process many different type of quantity question                    
    Input=type and requesting of sentence, the sentence and beginning sentence list  
    Output=class Sentence                                                            
    """

    for j in ResourcePool().sentence_starts:
        if sentence[2] == j[0]:
            if j[1] == '3':
                #This case is the same with y_n_question
                return y_n_ques(type, request, sentence[2:])

    analysis = y_n_ques(type, request, sentence[3:])

    #There is not sn in the sentence
    if not analysis.sn:
        analysis.sn = [NominalGroup(['a'], [sentence[2]], [], [], [])]

    else:
        #There is not direct object in the sentence
        analysis.sv[0].d_obj = [NominalGroup(['a'], [sentence[2]], [], [], [])]

    return analysis


def w_quest_how(type, sentence):
    """
    process many different type of how question                         
    Input=type of sentence, the sentence      Output=class Sentence                  
    """

    aux_list = other_functions.recover_aux_list()
    if sentence[1] in aux_list:
        analysis = y_n_ques(type, 'manner', sentence[1:])

        #The case when we have 'do' + ing form
        if analysis.sv[0].vrb_main[0].endswith('like'):
            analysis.aim = 'opinion'
        return analysis

    analysis = y_n_ques(type, sentence[1], sentence[2:])
    return analysis


def w_quest_which(type, request, sentence):
    """
    process which question                       
    Input=type of sentence, the sentence      Output=class Sentence                  
    """

    #We start by finding the nominal group
    gr = preprocessing.determination_nominal_group(sentence, 0, 'of')

    #If the nominal group contain just 2 elements
    if len(gr) == 2:
        return y_n_ques(type, sentence[1], sentence[2:])
    else:
        #After the first gr if there is no nominal group
        if not analyse_nominal_group.find_sn_pos(sentence, len(gr)):
            for i in ResourcePool().sentence_starts:
                #If just after we have an a auxiliary
                if sentence[len(gr)] == i[0] and i[1] == '3':
                    #With subject => it is a yes or no question form
                    if analyse_nominal_group.find_sn_pos(sentence, len(gr) + 1):
                        analysis = y_n_ques(type, request, sentence[len(gr):])
                        nominal_gr = other_sentence(type, request, gr)
                        analysis.sv[0].d_obj = nominal_gr.sn
                        return analysis
                #Else it is like a statement
            return other_sentence(type, request, sentence)

        #Else if not, the first nominal group is the subject
        else:
            analysis = other_sentence(type, request, sentence[len(gr):])
            nominal_gr = other_sentence(type, request, gr)
            analysis.sv[0].d_obj = nominal_gr.sn
            return analysis


def stc_start_subsentence(sentence):
    """
    process the subsentence at the beginning of the sentence
    Input=sentence                                          Output=class Sentence    
    """
    #We have to add punctuation if there is not
    if sentence[len(sentence) - 1] != '.' and sentence[len(sentence) - 1] != '?' and sentence[len(sentence) - 1] != '!':
        sentence = sentence + ['.']

    #We recover the subsentence
    for i in sentence:
        if i == ';' or i == '.' or i == '?' or i == '!':
            subsentence = sentence[1:sentence.index(i)]

            #We perform the 2 processing
            if sentence.index(i) != len(sentence) - 1:
                analysis = other_sentence(STATEMENT, '', sentence[sentence.index(i) + 1:])
            else:
                vg = VerbalGroup([], [], '', [], [], [], [], VerbalGroup.affirmative, [])
                analysis = Sentence('', '', [], [vg])
            break

    #We process the subsentence 
    analysis.sv[0].vrb_sub_sentence = analysis.sv[0].vrb_sub_sentence + dispatching(subsentence)
    if analysis.sv[0].vrb_sub_sentence:
        analysis.sv[0].vrb_sub_sentence[len(analysis.sv[0].vrb_sub_sentence) - 1].data_type = SUBSENTENCE + '+' + \
                                                                                              analysis.sv[
                                                                                                  0].vrb_sub_sentence[
                                                                                                  len(analysis.sv[
                                                                                                      0].vrb_sub_sentence) - 1].data_type
        if sentence[0][0] == ':':
            analysis.sv[0].vrb_sub_sentence[len(analysis.sv[0].vrb_sub_sentence) - 1].aim = sentence[0][1:]
        else:
            analysis.sv[0].vrb_sub_sentence[len(analysis.sv[0].vrb_sub_sentence) - 1].aim = sentence[0]

    return analysis


def w_quest_whose(type, request, sentence):
    """
    process many different type of whose question                       
    Input=type and requesting of sentence and the sentence                           
    Output=class Sentence                                                           
    """

    #init
    vg = VerbalGroup(['be'], [], '', [], [], [], [], VerbalGroup.affirmative, [])
    analysis = Sentence(type, request, [], [])


    #We replace 'whose' by 'that' to have a nominal group
    sentence[0] = 'that'

    #We recover the subject
    sentence = analyse_nominal_structure.recover_ns(sentence, analysis, 0)

    if sentence[1] == 'not':
        vg.state = 'negative'

    analysis.sv = [vg]
    return analysis


def w_quest_whom(type, request, sentence):
    """
    process whom question                                            
    Input=type and requesting of sentence and the sentence
    Output=class Sentence                                                            
    """

    #It is the same with yes or no question
    analysis = y_n_ques(type, request, sentence)

    #We have to add 'to' to the verb
    analysis.sv[0].vrb_main[0] += '+to'

    return analysis


def y_n_ques(type, request, sentence):
    """
    process the yes or no question from of a sentence
    Input=type and requesting of sentence and the sentence                           
    Output=class Sentence                                                            
    """

    #init
    vg = VerbalGroup([], [], '', [], [], [], [], VerbalGroup.affirmative, [])
    analysis = Sentence(type, request, [], [])
    modal = []
    stc = sentence

    #We start with determination of probably second verb in subsentence
    sentence = other_functions.find_scd_verb_sub(sentence)

    #We have to add punctuation if there is not
    if sentence == [] or sentence[0] == '.' or sentence[0] == '?' or sentence[0] == '!':
        #We have probably the aim as an adverb
        analyse_verbal_structure.find_adv([request], vg)
        analysis.aim = 'thing'
        analysis.sv = [vg]
        return analysis

    #We recover the auxiliary 
    aux = sentence[0]

    #We have to know if there is a modal
    if aux in ResourcePool().modal:
        modal = aux

    #If we have a negative form
    if sentence[1] == 'not':
        vg.state = VerbalGroup.negative
        #We remove 'not'
        sentence = sentence[:1] + sentence[2:]

    #Wrong is a noun but not followed by the determinant
    if sentence[1] == 'wrong' and request == 'thing':
        analysis.sn = [NominalGroup([], [], ['wrong'], [], [])]
        sentence = [sentence[0]] + sentence[2:]

    #In this case we have an imperative sentence
    elif analyse_nominal_group.find_sn_pos(sentence, 1) == [] and type != W_QUESTION:
        #We have to reput the 'not'
        if vg.state == VerbalGroup.negative:
            sentence = sentence[:1] + ['not'] + sentence[1:]
        return other_sentence(type, request, sentence)

    #We delete the auxiliary
    sentence = sentence[1:]

    #We have to separate the case using these, this or there
    if sentence[0] in ResourcePool().demonstrative_det and analyse_verb.infinitive([aux], 'present simple') == ['be']:
        #If we have a verb or an adverb just after (if not, we have a noun)
        if sentence[0].endswith('ed') or sentence[0].endswith('ing') or sentence[0].endswith('ly') or sentence[
            0] in ResourcePool().adverbs:
            #We recover this information and remove it
            analysis.sn = [NominalGroup([sentence[0]], [], [], [], [])]
            if sentence[0] == 'there' and aux == 'are':
                analysis.sn[0]._quantifier = 'SOME'
            sentence = sentence[1:]

    if not analysis.sn:
        #We recover the subject
        sentence = analyse_nominal_structure.recover_ns(sentence, analysis, 0)

    if aux == 'do' and not analyse_verbal_structure.can_be_imperative(sentence):
        return other_sentence('', '', stc)

    #If there is one element => it is an auxiliary => verb 'be'
    if len(sentence) == 0:
        vg.vrb_tense = analyse_verb.find_tense_statement(aux)
        vg.vrb_main = ['be']
    else:
        sentence = analyse_verbal_structure.delete_unusable_word(sentence)
        sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)
        vg.vrb_tense = analyse_verb.find_tense_question(sentence, aux)

        #We process the verb
        verb = analyse_verb.find_verb_question(sentence, aux, vg.vrb_tense)
        verb_main = analyse_verb.return_verb(sentence, verb, vg.vrb_tense)
        vg.vrb_main = [other_functions.convert_to_string(verb_main)]

        #We delete the verb if the aux is not the verb 'be'
        if vg.vrb_main != ['be']:
            sentence = sentence[sentence.index(verb[0]) + len(verb_main):]
        elif sentence[0] == 'be':
            sentence = sentence[1:]

        #Here we have special processing for different cases
        if sentence:
            #For 'what' descrition case
            if sentence[0] == 'like' and aux != 'would':
                vg.vrb_main = ['like']
                sentence = sentence[1:]

            #For 'how' questions with often
            elif sentence[0].endswith('ing') and not (sentence[0].endswith('thing')):
                vg.vrb_main[0] = vg.vrb_main[0] + '+' + sentence[0]
                sentence = sentence[1:]

        #We recover the conjunctive subsentence
        sentence = analyse_verbal_structure.process_conjunctive_sub(sentence, vg)

        #It verifies if there is a secondary verb
        sec_vrb = analyse_verbal_structure.find_scd_vrb(sentence)
        if sec_vrb:
            sentence = analyse_verbal_structure.process_scd_sentence(sentence, vg, sec_vrb)

        #We recover the subsentence
        sentence = analyse_verbal_structure.process_subsentence(sentence, vg)

        #Process relative changes
        sentence = analyse_verbal_structure.correct_i_compl(sentence, vg.vrb_main[0])

        sentence = analyse_verbal_structure.process_compare(sentence, vg)

        sentence = analyse_nominal_group.find_plural(sentence)
        #We recover the direct, indirect complement and the adverbial
        sentence = analyse_verbal_structure.recover_obj_iobj(sentence, vg)

        #We have to take off adverbs form the sentence
        sentence = analyse_verbal_structure.find_adv(sentence, vg)

    #We perform the processing with the modal
    if modal:
        vg.vrb_main = [modal + '+' + vg.vrb_main[0]]

    #If there is a forgotten
    sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)

    #In case there is a state verb followed by an adjective
    sentence = analyse_verbal_structure.state_adjective(sentence, vg)

    #We have to correct the mistake of the subject
    for p in ResourcePool().demonstrative_det:
        if analysis.sn and analysis.sn[0].det == [p] and analysis.sn[0].noun == []:
            if sentence != [0] and sentence[0] == '.' and sentence[0] == '?' and sentence[0] == '!':
                if sentence[0] in ResourcePool().proposals:
                    pass
                else:
                    analysis.sn[0].noun = [sentence[0]]
                    sentence = sentence[1:]
                    sentence = analyse_verbal_structure.state_adjective(sentence, vg)

    vg = analyse_verbal_structure.DOC_to_IOC(vg)

    while len(sentence) > 1:
        stc = analyse_verbal_structure.create_nom_gr(sentence, request)
        #We recover the direct, indirect complement and the adverbial
        stc = analyse_verbal_structure.recover_obj_iobj(stc, vg)
        if stc == sentence:
            #We leave the loop
            break
        else:
            sentence = stc

    vg = analyse_verbal_structure.refine_indirect_complement(vg)
    vg = analyse_verbal_structure.refine_subsentence(vg)
    vg = analyse_verbal_structure.DOC_to_IOC(vg)

    analysis.sv = [vg]
    return analysis


def other_sentence(type, request, sentence):
    """
    process the other from of a sentence                                
    Input=type and requesting of sentence and the sentence                               
    Output=class Sentence                                                            
    """

    #init
    vg = VerbalGroup([], [], '', [], [], [], [], VerbalGroup.affirmative, [])
    analysis = Sentence(type, request, [], [])
    modal = []

    if not sentence:
        return []

    #We have to add punctuation if there is not
    if sentence[len(sentence) - 1] not in ['.', '?', '!']:
        sentence = sentence + ['.']

    #We start with determination of probably second verb in subsentence
    sentence = other_functions.find_scd_verb_sub(sentence)

    #We search the subject
    sbj = analyse_nominal_group.find_sn_pos(sentence, 0)

    if sbj != [] or type == RELATIVE:
        #If we haven't a data type => it is a statement
        if type == '':
            analysis.data_type = STATEMENT


        #We have to separate the case using these, this or there
        if sentence[0] in ResourcePool().demonstrative_det and analyse_verb.infinitive([sentence[1]],
                                                                                       'present simple') == ['be']:
            #We recover this information and remove it
            analysis.sn = [NominalGroup([sentence[0]], [], [], [], [])]
            if sentence[0] == 'there' and sentence[1] == 'are':
                analysis.sn[0]._quantifier = 'SOME'
            sentence = sentence[1:]

        if not analysis.sn:
            #We recover the subject
            sentence = analyse_nominal_structure.recover_ns(sentence, analysis, 0)

        #End of the sentence? -> nominal sentence
        if sentence == [] or sentence[0] in ['.', '!', '?']:
            analysis.sv = []
            return analysis

        #We have to know if there is a modal
        if sentence[0] in ResourcePool().modal:
            modal = sentence[0]
            if modal == 'can' or modal == 'must' or modal == 'shall' or modal == 'may':
                sentence = sentence[1:]

        #We must take into account all possible cases to recover the sentence's tense
        if len(sentence) > 1 and sentence[1] == 'not':
            vg.state = VerbalGroup.negative

            #Before the negative form we have an auxiliary for the negation
            if sentence[0] == 'do' or sentence[0] == 'does' or sentence[0] == 'did':
                vg.vrb_tense = analyse_verb.find_tense_statement([sentence[0]])
                sentence = sentence[2:]
                sentence = analyse_verbal_structure.delete_unusable_word(sentence)
                sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)

            #There is a modal
            elif modal:
                sentence = [sentence[0]] + sentence[2:]
                sentence = analyse_verbal_structure.delete_unusable_word(sentence)
                sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)
                vg.vrb_tense = analyse_verb.find_tense_statement(sentence)

            else:
                #We remove 'not' and find the tense
                sentence = sentence[:1] + sentence[2:]
                sentence = analyse_verbal_structure.delete_unusable_word(sentence)
                sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)
                vg.vrb_tense = analyse_verb.find_tense_statement(sentence)

        #For the affirmative processing
        else:
            if sentence[0] == 'not':
                vg.state = VerbalGroup.negative
                sentence = sentence[1:]

            sentence = analyse_verbal_structure.delete_unusable_word(sentence)
            sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)
            vg.vrb_tense = analyse_verb.find_tense_statement(sentence)

        verb = analyse_verb.find_verb_statement(sentence, vg.vrb_tense)
        verb_main = analyse_verb.return_verb(sentence, verb, vg.vrb_tense)
        vg.vrb_main = [other_functions.convert_to_string(verb_main)]

        #We delete the verb
        sentence = sentence[sentence.index(verb[0]) + len(verb_main):]

        #We perform the processing with the modal
        if modal:
            vg.vrb_main = [modal + '+' + vg.vrb_main[0]]

    #This is a imperative form
    else:
        #re-init
        analysis.data_type = IMPERATIVE
        vg.vrb_tense = 'present simple'

        if sentence[0] in ResourcePool().proposals:
            sentence = ['.'] + sentence

        #Negative form
        if sentence[1] == 'not':
            sentence = sentence[sentence.index('not') + 1:]
            sentence = analyse_verbal_structure.delete_unusable_word(sentence)
            sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)
            vg.state = VerbalGroup.negative
        else:
            sentence = analyse_verbal_structure.delete_unusable_word(sentence)
            sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)

        #We process the verb
        verb = [sentence[0]]
        verb_main = analyse_verb.return_verb(sentence, verb, vg.vrb_tense)
        vg.vrb_main = [other_functions.convert_to_string(verb_main)]

        #We delete the verb
        sentence = sentence[sentence.index(verb[0]) + len(verb_main):]

    if sentence and sentence[-1] == '?':
        analysis.data_type = YES_NO_QUESTION

    #We recover the conjunctive subsentence
    sentence = analyse_verbal_structure.process_conjunctive_sub(sentence, vg)

    #It verifies if there is a secondary verb
    sec_vrb = analyse_verbal_structure.find_scd_vrb(sentence)
    if sec_vrb:
        sentence = analyse_verbal_structure.process_scd_sentence(sentence, vg, sec_vrb)

    #We recover the subsentence
    sentence = analyse_verbal_structure.process_subsentence(sentence, vg)

    if sentence != [] and vg.vrb_main != []:
        #Process relative changes
        sentence = analyse_verbal_structure.correct_i_compl(sentence, vg.vrb_main[0])

    sentence = analyse_verbal_structure.process_compare(sentence, vg)

    sentence = analyse_nominal_group.find_plural(sentence)
    #We recover the direct, indirect complement and the adverbial
    sentence = analyse_verbal_structure.recover_obj_iobj(sentence, vg)

    #We have to take off abverbs form the sentence
    sentence = analyse_verbal_structure.find_adv(sentence, vg)

    #In case there is a state verb followed by an adjective
    sentence = analyse_verbal_structure.state_adjective(sentence, vg)

    #If there is a forgotten
    sentence = analyse_verbal_structure.find_vrb_adv(sentence, vg)

    vg = analyse_verbal_structure.DOC_to_IOC(vg)

    while len(sentence) > 1:
        stc = analyse_verbal_structure.create_nom_gr(sentence, request)
        #We recover the direct, indirect complement and the adverbial
        stc = analyse_verbal_structure.recover_obj_iobj(stc, vg)
        if stc == sentence:
            #We leave the loop
            break
        else:
            sentence = stc

    vg = analyse_verbal_structure.refine_indirect_complement(vg)
    vg = analyse_verbal_structure.refine_subsentence(vg)
    vg = analyse_verbal_structure.DOC_to_IOC(vg)

    analysis.sv = [vg]
    return analysis


def sentences_analyzer(sentences):
    """
    This function is the basic function of parsing
    Input=list of sentences and beginning sentence list
    Output=list of class Sentence
    """

    #init
    class_sentence_list = []
    nom_gr = []
    y = 0

    #We process all sentences of the list
    for i in sentences:
        if i:
            #We have to add punctuation if there is not
            if i[-1] not in ['.', '?', '!']:
                i = i + ['.']
            class_sentence_list = class_sentence_list + dispatching(i)

    #Add some information if there is an interjection
    for s in class_sentence_list:
        #If there is an interjection we have to take the nominal group
        if s.data_type == INTERJECTION:
            nom_gr = s.sn
            #If there is an imperative sentence, we put the nominal group of interjection in the subject
        if nom_gr != [] and s.data_type == IMPERATIVE:
            s.sn = s.sn + nom_gr

    #To simplify the interpretation, we have to perform some changes
    for k in class_sentence_list:
        #If subject is 'there', we change it by the object
        if k.sn != [] and k.sn[0].det == ['there']:
            k.sn = k.sv[0].d_obj
            k.sv[0].d_obj = []

        #If sentence is empty, we take off the verb
        if k.sv != [] and (k.sv[0].vrb_main == ['.'] or k.sv[0].vrb_main == ['?'] or k.sv[0].vrb_main == ['!']):
            k.sv[0].vrb_main = []
            if k.data_type == IMPERATIVE:
                k.data_type = STATEMENT

        #If we have imperative with verb 'see' => end
        if k.data_type == IMPERATIVE and \
                        k.sv[0].vrb_main == ['see'] and \
                        len(k.sv[0].d_obj) > 0 and \
                        k.sv[0].d_obj[0].noun == ['you']:
            k.data_type = END
            k.aim = ''
            k.sv = []
            k.sn = []

    return class_sentence_list

#!/usr/bin/python # -*- coding: utf-8 -*- Created by <NAME>                                                         25/06/2010                                                                         The package contains functions to analyse all sentence of a utterance              Functions:                                      dispatching : to distribute the sentence               separ_sentence : to process the beginning of the sentence      exclama_sentence : to process exclamatively sentence                          w_quest_where : to process many different type of where question           w_quest_class : to process what question about classification        w_quest_what  : to process many different type of what question                      w_quest_quant : to process many different type of how question     w_quest_how : to process many different type of how question     w_quest_which : to process which question                         stc_start_subsentence : to process the subsentence at the beginning of the sentence                                w_quest_whose : to process many different type of whose question        w_quest_whom : to process whom question     y_n_ques : to process the yes or no question from of a sentence                      other_sentence : to process the other from of a sentence                             sentences_analyzer : is the basic function of parsing distributes the sentence according to:                                  Their functionality and their type                                                    Input=sentence, beginning sentence list          Output=class Sentence #For ending dialogue #When others #If we find a knowing case #For #It's a w_question or subsentence #If there is which or no nominal group it is a question #Here we have the condition of the subsentences #For 'when' #If we remove the first word => it becomes like y_n_question #For 'where' #For 'what' #Here we have to use a specific processing for 'type' and 'kind' #We start by processing the end of the sentence like a y_n_question #For other type of 'what' question #For 'how' #We replace 'about' by 'is' to have a y_n_question #For other type of 'how' question #For 'why' #For 'whose' #For 'who' #For 'which' #For 'to whom' #It's a y_n_question #It's a conditional sentence #Agree #Disagree #Gratulation #Interjunction #For exclamatively #It's a statement or an imperative sentence #Default case process the beginning of the sentence                            Input=the sentence                                   Output=class Sentence #If we have good followed by another word it can be start #init #We put the first sentence in the aim #We process the end of the sentence as a complete sentence #In this case, it is the end of the sentence process exclamatively sentence                            Input=the sentence                                   Output=class Sentence #We recover the subject #It is an exclamation sentence #We recover the subject #If we have an imperative it can be forced process many different type of where question                            Input=type and requesting of sentence, the sentence      Output=class Sentence #If there is 'form' at the end => question about the origin #If we remove the first word => it becomes like y_n_question #If we remove the first word => it becomes like y_n_question process what question about classification                            Input=sentence                                       Output=class Sentence #The direct object must be empty process many different type of what question                             Input=type of sentence, the sentence and position of subject                           Output=class Sentence #We start with a processing with the function of y_n_question's case #The case when we have 'happen' #The case when we have 'think' #The case when we have 'like' + conditional #The case when we have 'do' + ing form #There is a noun before the auxiliary #We will use the same code as the which questions #We need to have a nominal group at the beginning process many different type of quantity question                         Input=type and requesting of sentence, the sentence and beginning sentence list       Output=class Sentence #This case is the same with y_n_question #There is not sn in the sentence #There is not direct object in the sentence process many different type of how question                              Input=type of sentence, the sentence      Output=class Sentence #The case when we have 'do' + ing form process which question                            Input=type of sentence, the sentence      Output=class Sentence #We start by finding the nominal group #If the nominal group contain just 2 elements #After the first gr if there is no nominal group #If just after we have an a auxiliary #With subject => it is a yes or no question form #Else it is like a statement #Else if not, the first nominal group is the subject process the subsentence at the beginning of the sentence     Input=sentence                                          Output=class Sentence #We have to add punctuation if there is not #We recover the subsentence #We perform the 2 processing #We process the subsentence process many different type of whose question                            Input=type and requesting of sentence and the sentence                                Output=class Sentence #init #We replace 'whose' by 'that' to have a nominal group #We recover the subject process whom question                                                 Input=type and requesting of sentence and the sentence     Output=class Sentence #It is the same with yes or no question #We have to add 'to' to the verb process the yes or no question from of a sentence     Input=type and requesting of sentence and the sentence                                Output=class Sentence #init #We start with determination of probably second verb in subsentence #We have to add punctuation if there is not #We have probably the aim as an adverb #We recover the auxiliary #We have to know if there is a modal #If we have a negative form #We remove 'not' #Wrong is a noun but not followed by the determinant #In this case we have an imperative sentence #We have to reput the 'not' #We delete the auxiliary #We have to separate the case using these, this or there #If we have a verb or an adverb just after (if not, we have a noun) #We recover this information and remove it #We recover the subject #If there is one element => it is an auxiliary => verb 'be' #We process the verb #We delete the verb if the aux is not the verb 'be' #Here we have special processing for different cases #For 'what' descrition case #For 'how' questions with often #We recover the conjunctive subsentence #It verifies if there is a secondary verb #We recover the subsentence #Process relative changes #We recover the direct, indirect complement and the adverbial #We have to take off adverbs form the sentence #We perform the processing with the modal #If there is a forgotten #In case there is a state verb followed by an adjective #We have to correct the mistake of the subject #We recover the direct, indirect complement and the adverbial #We leave the loop process the other from of a sentence                                     Input=type and requesting of sentence and the sentence                                    Output=class Sentence #init #We have to add punctuation if there is not #We start with determination of probably second verb in subsentence #We search the subject #If we haven't a data type => it is a statement #We have to separate the case using these, this or there #We recover this information and remove it #We recover the subject #End of the sentence? -> nominal sentence #We have to know if there is a modal #We must take into account all possible cases to recover the sentence's tense #Before the negative form we have an auxiliary for the negation #There is a modal #We remove 'not' and find the tense #For the affirmative processing #We delete the verb #We perform the processing with the modal #This is a imperative form #re-init #Negative form #We process the verb #We delete the verb #We recover the conjunctive subsentence #It verifies if there is a secondary verb #We recover the subsentence #Process relative changes #We recover the direct, indirect complement and the adverbial #We have to take off abverbs form the sentence #In case there is a state verb followed by an adjective #If there is a forgotten #We recover the direct, indirect complement and the adverbial #We leave the loop This function is the basic function of parsing     Input=list of sentences and beginning sentence list     Output=list of class Sentence #init #We process all sentences of the list #We have to add punctuation if there is not #Add some information if there is an interjection #If there is an interjection we have to take the nominal group #If there is an imperative sentence, we put the nominal group of interjection in the subject #To simplify the interpretation, we have to perform some changes #If subject is 'there', we change it by the object #If sentence is empty, we take off the verb #If we have imperative with verb 'see' => end