//
// David Moews, 2009
//

//
// Many verbs have not been implemented
//

// Longer prefixes should be listed first.
var irregular_present_endings =
[

// verbs + compounds
['boire', ['bois','bois','boit','buvons','buvez','boivent','bu']], 
['pourvoir', ['pourvois','pourvois','pourvoit','pourvoyons','pourvoyez','pourvoient','pourvu']], 
['tenir',['tiens','tiens','tient','tenons','tenez','tiennent','tenu']],
['venir',['viens','viens','vient','venons','venez','viennent','venu']],
['asseoir',['assieds','assieds','assied','asseyons','asseyez','asseyent','assis']],
['bouillir',['bous','bous','bout','bouillons','bouillez','bouillent','bouilli']],
['écrire', ['écris','écris','écrit','écrivons','écrivez','écrivent','écrit']],

// dire + derivatives
['contredire',['contredis','contredis','contredit','contredisons','contredisez','contredisent','contredit']],
['dédire',['dédis','dédis','dédit','dédisons','dédisez','dédisent','dédit']],
['interdire',['interdis','interdis','interdit','interdisons','interdisez','interdisent','interdit']],
['médire',['médis','médis','médit','médisons','médisez','médisent','médit']],
['prédire',['prédis','prédis','prédit','prédisons','prédisez','prédisent','prédit']],
['dire',['dis','dis','dit','disons','dites','disent','dit']],

// include connaître so connaître doesn't get treated as derivative of naître
['connaître', ['connais','connais','connaît','connaissons','connaissez','connaissent','connu']],  

// -cevoir (apercevoir, décevoir, percevoir, recevoir, etc.)
// must come before voir
['cevoir',['çois','çois','çoit','cevons','cevez','çoivent','çu']],

// more verbs + compounds
['coudre',['couds','couds','coud','cousons','cousez','cousent','cousu']],
['courir',['cours','cours','court','courons','courez','courent','couru']],
['cueillir',['cueille','cueilles','cueille','cueillons','cueillez','cueillent','cueilli']],
['devoir',['dois','dois','doit','devons','devez','doivent','dû']],
['dormir',['dors','dors','dort','dormons','dormez','dorment','dormi']],
['mouvoir',['meus','meus','meut','mouvons','mouvez','meuvent','mû']],
['suivre',['suis','suis','suit','suivons','suivez','suivent','suivi']],
['faire', ['fais', 'fais', 'fait', 'faisons', 'faites', 'font','fait']],
['savoir', ['sais', 'sais', 'sait', 'savons', 'savez', 'savent','su']],
['fuir', ['fuis','fuis','fuit','fuyons','fuyez','fuient','fui']],
['haïr', ['hais','hais','hait','haïssons','haïssez','haïssent','haï']],
['lire',['lis','lis','lit','lisons','lisez','lisent','lu']],
['mentir',['mens','mens','ment','mentons','mentez','mentent','menti']],
['sentir',['sens','sens','sent','sentons','sentez','sentent','senti']],
['moudre',['mouds','mouds','moud','moulons','moulez','moulent','moulu']],
['mourir',['meurs','meurs','meurt','mourons','mourez','meurent','mort']],
['naître', ['nais','nais','naît','naissons','naissez','naissent','né']],  
['nuire',['nuis','nuis','nuit','nuisons','nuisez','nuisent','nui']],    
['luire',['luis','luis','luit','luisons','luisez','luisent','lui']],    
['plaire',['plais','plais','plaît','plaisons','plaisez','plaisent','plu']],
['prendre',['prends','prends','prend','prenons','prenez','prennent','pris']],
['valoir',['vaux','vaux','vaut','valons','valez','valent','valu']],
['rompre',['romps','romps','rompt','rompons','rompez','rompent','rompu']],
['voir',['vois','vois','voit','voyons','voyez','voient','vu']], // must go after devoir, mouvoir, savoir
['vivre',['vis','vis','vit','vivons','vivez','vivent','vécu']],
['vêtir',['vêts','vêts','vêt','vêtons','vêtez','vêtent','vêtu']],
['servir',['sers','sers','sert','servons','servez','servent','servi']],
['taire',['tais','tais','tait','taisons','taisez','taisent','tu']],
['partir',['pars','pars','part','partons','partez','partent','parti']],
['repentir',['repens','repens','repent','repentons','repentez','repentent','repenti']],
['vaincre',['vaincs','vaincs','vainc','vainquons','vainquez','vainquent','vaincu']],

// suffixes
['scrire', ['scris','scris','scrit','scrivons','scrivez','scrivent','scrit']],  // e.g. inscrire
['aillir',['aille','ailles','aille','aillons','aillez','aillent','ailli']],   // e.g. assaillir
['soudre', ['sous','sous','sout','solvons','solvez','solvent','sous']],  // e.g. absoudre
['quérir', ['quiers','quiers','quiert','quérons','quérez','quièrent','quis']],   // e.g. acquérir
['oître', ['ois','ois','oît','oissons','oissez','oissent','u']],   // e.g. accroître
['aître', ['ais','ais','aît','aissons','aissez','aissent','u']],  // e.g. connaître
['ettre',['ets','ets','et','ettons','ettez','ettent','is']],      // e.g. mettre
['uire',['uis','uis','uit','uisons','uisez','uisent','uit']],    // e.g. conduire
['clure',['clus','clus','clut','cluons','cluez','cluent','clu']], // e.g. conclure
['aindre',['ains','ains','aint','aignons','aignez','aignent','aint']], // e.g. craindre
['eindre',['eins','eins','eint','eignons','eignez','eignent','eint']], // e.g. peindre
['oindre',['oins','oins','oint','oignons','oignez','oignent','oint']], // e.g. joindre
['vrir',['vre','vres','vre','vrons','vrez','vrent','vert']], // e.g. ouvrir, couvrir
['frir',['fre','fres','fre','frons','frez','frent','fert']], // e.g. souffrir
['raire', ['rais','rais','rait','rayons','rayez','raient','rait']],   // braire, raire, traire, abstraire, distraire, extraire, soustraire


// verb rire and its compounds (has to be put after -scrire ending and verb écrire)
['rire',['ris','ris','rit','rions','riez','rient','ri']],

// -tre
['tre', ['s','s','','tons','tez','tent','tu']],    // e.g. battre

// so-called regular -re
['re', ['s','s','','ons','ez','ent','u']], // -andre, -endre, -ondre, -erdre, -ordre (e.g., rendre, attendre)

// regular -ir (group 2)
['ir', ['is','is','it','issons','issez','issent','i']]
];

var irregular_present =
[
// Highly irregular verbs (x/c faire, savoir, for which see above)
['être', ['suis', 'es', 'est', 'sommes', 'êtes', 'sont','été']],
['aller', ['vais', 'vas', 'va', 'allons', 'allez', 'vont','allé']],
['avoir', ['ai', 'as', 'a', 'avons', 'avez', 'ont','eu']],
['pouvoir', ['peux', 'peux', 'peut', 'pouvons', 'pouvez', 'peuvent','pu']],
['vouloir', ['veux', 'veux', 'veut', 'voulons', 'voulez', 'veulent','voulu']],
// 
// regular group 2 (would otherwise be treated as irregular)
// 
['asservir',['asservis','asservis','asservit','asservissons','asservissez','asservissent','asservi']],
['jaillir', ['jaillis','jaillis','jaillit','jaillissons','jaillissez','jaillissent','jailli']],
['saillir', ['saillis','saillis','saillit','saillissons','saillissez','saillissent','sailli']],
['répartir',['répartis','répartis','répartit','répartissons','répartissez','répartissent','réparti']],
['maudire',['maudis','maudis','maudit','maudissons','maudissez','maudissent','maudit']],   // Conjugates as group 2 despite -ire ending
// 
//  Others
// 
['bruire', ['bruis','bruis','bruit','bruissons','bruissez','bruissent','brui']],
['choir',['chois','chois','choit','choyons','choyez','choient','chu']],
['déchoir',['déchois','déchois','déchoit','déchoyons','déchoyez','déchoient','déchu']],
['circoncire',['circoncis','circoncis','circoncit','circoncisons','circoncisez','circoncisent','circoncis']],
['confire',['confis','confis','confit','confisons','confisez','confisent','confit']],
['déconfire',['déconfis','déconfis','déconfit','déconfisons','déconfisez','déconfisent','déconfit']],
['suffire',['suffis','suffis','suffit','suffisons','suffisez','suffisent','suffi']],
['clore',['clos','clos','clôt','closons','closez','closent','clos']],
['enclore',['enclos','enclos','enclot','enclosons','enclosez','enclosent','enclos']],
['éclore',['éclos','éclos','éclot','éclosons','éclosez','éclosent','éclos']],
['déclore',['déclos','déclos','déclôt','déclosons','déclosez','déclosent','déclos']],
['forclore',['forclos','forclos','forclôt','forclosons','forclosez','forclosent','forclos']],
['foutre',['fous','fous','fout','foutons','foutez','foutent','foutu']],
['amuïr', ['amuis','amuis','amuit','amuïssons','amuïssez','amuïssent','amuï']],
['résoudre', ['résous','résous','résout','résolvons','résolvez','résolvent','résolu']],
['croître', ['croîs','croîs','croît','croissons','croissez','croissent','crû']],
['croire', ['crois','crois','croit','croyons','croyez','croient','cru']],
['recroître', ['recrois','recrois','recroît','recroissons','recroissez','recroissent','recrû']],
['promouvoir',['promeus','promeus','promeut','promouvons','promouvez','promeuvent','promu']],
['émouvoir',['émeus','émeus','émeut','émouvons','émouvez','émeuvent','ému']],
['falloir',['faus','faus','faut','fallons','fallez','faillent','fallu']],
['frire',['fris','fris','frit','frions','friez','frient','frit']],
['gésir',['gis','gis','gît','gisons','gisez','gisent','gisi']],
['inclure',['inclus','inclus','inclut','incluons','incluez','incluent','inclus']], 
['occlure',['occlus','occlus','occlut','occluons','occluez','occluent','occlus']],
['ouïr',['ois','ois','oit','oyons','oyez','oient', 'ouï']],
['pleuvoir',['pleus','pleus','pleut','pleuvons','pleuvez','pleuvent','plu']],
['recroître',['recrois','recrois','recroît','recroissons','recroissez','recroissent','recrû']],
['résoudre', ['résous','résous','résout','résolvons','résolvez','résolvent','résolu']],  
['sortir',['sors','sors','sort','sortons','sortez','sortent','sorti']],
['surseoir',['sursois','sursois','sursoit','sursoyons','sursoyez','sursoient','sursis']],
['faillir',['faux','faux','faut','faillons','faillez','faillent','failli']]
];

//
// Stem-changing -er verbs.  Returns vector with
// first member pseudo-infinitive with the stem change, 
// second member indicating whether or not this change should be 
// applied to the conditional & future tenses.
//
// Does not handle spelling changes (-cer, -ger.)
//
function is_stem_changing(verb)
{
  var verb2;

  verb2 = verb;

  // é -> è   (eCer); might also be spelling change
  if (verb.slice(-4) == 'érer' || verb.slice(-4) == 'éner' ||
      verb.slice(-4) == 'éder' || verb.slice(-4) == 'émer' ||
      verb.slice(-4) == 'éger' || verb.slice(-4) == 'éser' ||
      verb.slice(-4) == 'écer' || verb.slice(-4) == 'éper' ||
      verb.slice(-4) == 'éter' || verb.slice(-4) == 'éler')
  {
    verb2 = verb.slice(0, -4) + 'è' + verb.slice(-3);
    return [verb2, false];
  }
  // é -> è   (eCCer)
  else if (verb.slice(-5) == 'égler' || verb.slice(-5) == 'égner' ||
           verb.slice(-5) == 'étrer' || verb.slice(-5) == 'ébrer' ||
           verb.slice(-5) == 'évrer' || verb.slice(-5) == 'écrer' ||
           verb.slice(-5) == 'équer' || verb.slice(-5) == 'égrer' ||
           verb.slice(-5) == 'éguer' || verb.slice(-5) == 'écher')
  {
    verb2 = verb.slice(0, -5) + 'è' + verb.slice(-4);
    return [verb2, false];
  }
  // e -> è   (eCer); might also be spelling change
  else if (verb.slice(-4) == 'ever' || verb.slice(-4) == 'eser' ||
      verb.slice(-4) == 'emer' || verb.slice(-4) == 'ener' ||
      verb.slice(-4) == 'erer' || verb.slice(-4) == 'eper' ||
      verb.slice(-4) == 'ecer' ||
      verb == 'acheter' || verb == 'préacheter' || verb == 'racheter' ||
      verb == 'celer' || verb == 'déceler' || verb == 'receler' ||
      verb == 'ciseler' || verb == 'aciseler' || verb == 'reciseler' ||
      verb == 'écarteler' || verb == 'corseter' ||
      verb == 'crocheter' || verb == 'démanteler' ||
      verb == 'haleter' || verb == 'harceler' ||
      verb == 'geler' || verb == 'congeler' ||
      verb == 'dégeler' || verb == 'décongeler' || verb == 'désurgeler' ||
      verb == 'recongeler' || verb == 'regeler' || verb == 'resurgeler' ||
      verb == 'surgeler' ||
      verb == 'marteler' || verb == 'modeler' || verb == 'remodeler' ||
      verb == 'peler')
  {
    verb2 = verb.slice(0, -4) + 'è' + verb.slice(-3);
    return [verb2, true];
  }
  // doubled consonant (eler, eter)
  else if (verb.slice(-4) == 'eler' || verb.slice(-4) == 'eter')
  {
    verb2 = verb.slice(0, -3) + verb.slice(-3, -2) + verb.slice(-3, -2) + 'er';
    return [verb2, true];
  }
  // e -> è   (eCCer)
  else if (verb.slice(-5) == 'evrer')
  {
    verb2 = verb.slice(0, -5) + 'è' + verb.slice(-4);
    return [verb2, true];
  }
  else if (verb.slice(-4) == 'oyer' || verb.slice(-4) == 'uyer')
  {
    // Irregular; stem change
    verb2 = verb.slice(0, -3) + 'ier';
    return [verb2, true];
  } 
  else
  // Not stem-changing
  {
    return [verb, true];
  }
}

// returns [group, stem-changing]; group 4 for etre/avoir;
// stem-changing only set for group 1
function get_group(verb)
{
  var i;

  if (verb == 'être' || verb == 'avoir')
     return [4, false];

  // regular -ir verbs that are in the irregular list
  if (verb == 'maudire' || verb == 'asservir' ||
      verb == 'répartir' || verb == 'jaillir' || verb == 'saillir')
     return [2, false];

  for (i = 0; i < irregular_present.length; i++)
  {
    if (verb == irregular_present[i][0])
       return [3, false];
  }

  // Avoid checking for regular -ir verbs
  for (i = 0; i < irregular_present_endings.length - 1; i++)
  {
    if (verb.slice(-irregular_present_endings[i][0].length) ==
        irregular_present_endings[i][0])
        return [3, false];
  }

  if (verb.slice(-2) == 'ir')
     return [2, false];

  if (verb.slice(-3) == 'cer' ||
      verb.slice(-3) == 'ger' ||
      is_stem_changing(verb)[0] != verb)
     return [1, true];
  else
     return [1, false];
}

function get_french_indicative_and_pp(verb)
{
  var verb2, temp, temp2, i;

  for (i = 0; i < irregular_present.length; i++)
  {
    if (verb == irregular_present[i][0])
    {
      temp = irregular_present[i][1];
      return [[temp[0], temp[1], temp[2], temp[3], temp[4], temp[5]], temp[6]];
    }
  }

  for (i = 0; i < irregular_present_endings.length; i++)
  {
    if (verb.slice(-irregular_present_endings[i][0].length) ==
        irregular_present_endings[i][0])
    {
      temp2 = verb.slice(0, -irregular_present_endings[i][0].length);
      temp = irregular_present_endings[i][1];
      return [[temp2 + temp[0], temp2 + temp[1], temp2 + temp[2],
               temp2 + temp[3], temp2 + temp[4], temp2 + temp[5]],
              temp2 + temp[6]];
    }
  }
  verb2 = is_stem_changing(verb)[0];

  if (verb.slice(-3) == 'cer')
  {
    // Spelling change
    temp = verb.slice(0, -3);
    temp2 = verb2.slice(0, -3);
    return [[temp2 + 'ce', temp2 + 'ces', temp2 + 'ce',
             temp + 'çons', temp + 'cez', temp2 + 'cent'],
            temp + 'cé'];
  }
  else if (verb.slice(-3) == 'ger')
  {
    // Spelling change
    temp = verb.slice(0, -3);
    temp2 = verb2.slice(0, -3);
    return [[temp2 + 'ge', temp2 + 'ges', temp2 + 'ge',
             temp + 'geons', temp + 'gez', temp2 + 'gent'],
            temp + 'gé'];
  }
  else if (verb.slice(-2) == 'er')
  {
    temp = verb.slice(0, -2);
    temp2 = verb2.slice(0, -2);
    return [[temp2 + 'e', temp2 + 'es', temp2 + 'e',
             temp + 'ons', temp + 'ez', temp2 + 'ent'],
            temp + 'é'];
  }
}

var irregular_subjunctive_endings = [
// Irreg. stems, same endings
['faire', ['fasse', 'fasses', 'fasse', 'fassions', 'fassiez', 'fassent']],
['savoir', ['sache', 'saches', 'sache', 'sachions', 'sachiez', 'sachent']],
['valoir', ['vaille', 'vailles', 'vaille', 'valions', 'valiez', 'vaillent']]
];

var irregular_subjunctive = [
// Regular
['faillir',['faillisse','faillisses','faillisse','faillissions','faillissiez','faillissent']],
// Regular but put here b/c valoir and its compounds are otherwise irregular
['prévaloir', ['prévale','prévales','prévale','prévalions','prévaliez','prévalent']],
// Irreg. stems, same endings
['aller', ['aille', 'ailles', 'aille', 'allions', 'alliez', 'aillent']],
['pouvoir', ['puisse', 'puisses', 'puisse', 'puissions', 'puissiez', 'puissent']],
['vouloir', ['veuille', 'veuilles', 'veuille', 'voulions', 'vouliez', 'veuillent']],
// other
['avoir', ['aie', 'aies', 'ait', 'ayons', 'ayez', 'aient']],
['être', ['sois', 'sois', 'soit', 'soyons', 'soyez', 'soient']]
];

function get_french_subjunctive(verb, indicative)
{
  var i, temp, temp2;

  for (i = 0; i < irregular_subjunctive.length; i++)
  {
    if (verb == irregular_subjunctive[i][0])
       return irregular_subjunctive[i][1];
  }

  for (i = 0; i < irregular_subjunctive_endings.length; i++)
  {
    if (verb.slice(-irregular_subjunctive_endings[i][0].length) == 
        irregular_subjunctive_endings[i][0])
    {
      temp = verb.slice(0, -irregular_subjunctive_endings[i][0].length);
      temp2 = irregular_subjunctive_endings[i][1];
      return [temp + temp2[0], temp + temp2[1], temp + temp2[2],
              temp + temp2[3], temp + temp2[4], temp + temp2[5]];
    }
  }

  temp = indicative[5].slice(0, -3);
  if (indicative[3].slice(-5) == 'geons')
  // Spelling change
  {
    temp2 = indicative[3].slice(0, -5) + 'g';
  } else if (indicative[3].slice(-4) == 'çons')
  // Spelling change
  {
    temp2 = indicative[3].slice(0, -4) + 'c';
  } else
  {
    temp2 = indicative[3].slice(0, -3);
  }
  return [temp + 'e', temp + 'es', temp + 'e', 
          temp2 + 'ions', temp2 + 'iez', temp + 'ent'];
}

var simple_past_endings =
[
// Include connaître so that connaître doesn't get treated as a derivative of naître
['connaître', 'conn', 2],

// -cevoir (apercevoir, décevoir, percevoir, recevoir, etc.)
// must come before voir
['cevoir','ç', 2],

// verbs + derivatives
['venir', 
   [['vins', 'vins', 'vint', 'vînmes', 'vîntes', 'vinrent'],
    ['vinsse','vinsses','vînt','vinssions','vinssiez','vinssent']
     ]],
['tenir', 
   [['tins', 'tins', 'tint', 'tînmes', 'tîntes', 'tinrent'],
    ['tinsse','tinsses','tînt','tinssions','tinssiez','tinssent']
     ]],
['mourir', 
   [['mourus', 'mourus', 'mourut', 'mourûmes', 'mourûtes', 'moururent'],
    ['mourusse','mourusses','mourût','mourussions','mourussiez','mourussent']
     ]],
['haïr',
    [['haïs', 'haïs', 'haït', 'haïmes', 'haïtes', 'haïrent'],
     ['haïsse', 'haïsses', 'haït', 'haïssions', 'haïssiez', 'haïssent']
    ]],

['boire', 'b', 2],
['pourvoir', 'pourv', 2],
['courir', 'cour', 2],
['devoir', 'd', 2],
['lire', 'l', 2],
['savoir', 's', 2],
['valoir', 'val', 2],
['vivre', 'véc', 2],
['mouvoir', 'm', 2],
['taire', 't', 2],
['vaincre','vainqu', 1],

['asseoir', 'ass', 1],
['écrire', 'écriv', 1],
['faire', 'f', 1],
['naître', 'naqu', 1],
['prendre', 'pr', 1],
['voir', 'v', 1],       // must come after savoir, valoir, devoir, mouvoir
['coudre', 'cous', 1],
['moudre', 'moul', 2],
['plaire', 'pl', 2],
['quérir', 'qu', 1],

// suffixes
// Longer suffixes first
['ettre', '', 1],              // e.g. mettre
['uire','uis', 1],             // e.g. conduire
['scrire', 'scriv', 1],        // e.g. inscrire
['oindre', 'oign', 1],         // e.g. joindre
['eindre', 'eign', 1],         // e.g. peindre
['aindre', 'aign', 1],         // e.g. craindre
['ire', '', 1],                // dire, rire, circoncire, ...

['aître', '', 2],              // e.g. connaître
['oître', '', 2],              // e.g. accroître
['clure', 'cl', 2],            // e.g. conclure

['ir', '', 1],                 // regular -ir
['re', '', 1],                 // so-called regular -re (-andre, -endre, -ondre, -erdre, -ordre)

// Finally -er verbs (not irregular)
['cer', [['çai', 'ças', 'ça', 'çâmes', 'çâtes', 'cèrent'],
         ['çasse', 'çasses', 'çât', 'çassions', 'çassiez', 'çassent']
        ]],
['ger', [['geai', 'geas', 'gea', 'geâmes', 'geâtes', 'gèrent'],
         ['geasse', 'geasses', 'geât', 'geassions', 'geassiez', 'geassent']
        ]],
['er', [['ai', 'as', 'a', 'âmes', 'âtes', 'èrent'],
        ['asse', 'asses', 'ât', 'assions', 'assiez', 'assent']
        ]]
];

var irregular_simple_past =
[
['avoir', 'e', 2],
['croire', 'cr', 2],
['falloir', 'fall', 2],
['pleuvoir', 'pl', 2],
['pouvoir', 'p', 2],
['vouloir', 'voul', 2],
['résoudre', 'résol', 2],
['choir', 'ch', 2],
['déchoir', 'déch', 2],
['être', 'f', 2],
['surseoir', 'surs', 1],
['amuïr',
    [['amuïs', 'amuïs', 'amuït', 'amuïmes', 'amuïtes', 'amuïrent'],
     ['amuïsse', 'amuïsses', 'amuït', 'amuïssions', 'amuïssiez', 'amuïssent']
    ]],
['croître',
    [['crûs','crûs','crût','crûmes','crûtes','crûrent'],
     ['crûsse','crûsses','crût','crûssions','crûssiez','crûssent']
    ]],
['ouïr',
    [['ouïs','ouïs','ouït','ouîmes','ouîtes','ouïrent'],
     ['ouïsse','ouïsses','ouït','ouïssions','ouïssiez','ouïssent']
    ]]
];

function get_french_simple_past_and_imperfect_subjunctive(verb)
{
  var i, temp, temp2;

  for (i = 0; i < irregular_simple_past.length; i++)
  {
    if (verb == irregular_simple_past[i][0])
    {
      if (irregular_simple_past[i].length == 2)
      {
        return irregular_simple_past[i][1];
      } else
      {
        temp = irregular_simple_past[i][1];
        if (irregular_simple_past[i][2] == 1)
        {
          return [[temp + 'is', temp + 'is', temp + 'it',
                   temp + 'îmes', temp + 'îtes', temp + 'irent'],
                  [temp + 'isse', temp + 'isses', temp + 'ît',
                   temp + 'issions', temp + 'issiez', temp + 'issent']];
        } else
        {
          return  [[temp + 'us', temp + 'us', temp + 'ut',
                    temp + 'ûmes', temp + 'ûtes', temp + 'urent'],
                   [temp + 'usse', temp + 'usses', temp + 'ût',
                    temp + 'ussions', temp + 'ussiez', temp + 'ussent']];
        }
      }
    }
  }

  for (i = 0; i < simple_past_endings.length; i++)
  {
    if (verb.slice(-simple_past_endings[i][0].length) == 
        simple_past_endings[i][0])
    {
      if (simple_past_endings[i].length == 2)
      {
        temp = verb.slice(0, -simple_past_endings[i][0].length);
        temp2 = simple_past_endings[i][1];

        return [[temp + temp2[0][0], temp + temp2[0][1], temp + temp2[0][2],
                 temp + temp2[0][3], temp + temp2[0][4], temp + temp2[0][5]],
                [temp + temp2[1][0], temp + temp2[1][1], temp + temp2[1][2],
                 temp + temp2[1][3], temp + temp2[1][4], temp + temp2[1][5]]];
      } else
      {
        temp = verb.slice(0, -simple_past_endings[i][0].length) + simple_past_endings[i][1];
        if (simple_past_endings[i][2] == 1)
        {
          return [[temp + 'is', temp + 'is', temp + 'it',
                   temp + 'îmes', temp + 'îtes', temp + 'irent'],
                  [temp + 'isse', temp + 'isses', temp + 'ît',
                   temp + 'issions', temp + 'issiez', temp + 'issent']];
        } else
        {
          return  [[temp + 'us', temp + 'us', temp + 'ut',
                    temp + 'ûmes', temp + 'ûtes', temp + 'urent'],
                   [temp + 'usse', temp + 'usses', temp + 'ût',
                    temp + 'ussions', temp + 'ussiez', temp + 'ussent']];
        }
      }
    }
  }
}

function get_french_imperfect(verb, indicative)
{
  var temp;

  if (verb == 'être')
  {
    return ['étais', 'étais', 'était', 'étions', 'étiez', 'étaient'];
  }
  else if (verb.slice(-3) == 'ger')
  {
    // Spelling change
    temp = indicative[3].slice(0, -5);

    return [temp + 'geais', temp + 'geais', temp + 'geait',
            temp + 'gions', temp + 'giez', temp + 'geaient'];
  }
  else if (verb.slice(-3) == 'cer')
  {
    // Spelling change
    temp = indicative[3].slice(0, -4);

    return [temp + 'çais', temp + 'çais', temp + 'çait',
            temp + 'cions', temp + 'ciez', temp + 'çaient'];
  } 
  else
  {
    temp = indicative[3].slice(0, -3);

    return [temp + 'ais', temp + 'ais', temp + 'ait',
            temp + 'ions', temp + 'iez', temp + 'aient'];
  }
}

var irregular_future_conditional_endings =
[
['tenir', 'tiendr'],
['venir', 'viendr'],
['envoyer', 'enverr'],   // envoyer, renvoyer
['cevoir', 'cevr'],      // -cevoir; must come before voir
['mouvoir', 'mouvr'],    // must come before voir
['devoir', 'devr'],      // must come before voir
['savoir', 'saur'],      // must come before voir
['pourvoir', 'pourvoir'],      // must come before voir
['voir', 'verr'],
['quérir', 'querr'],     // e.g. acquérir
['asseoir','assiér'],
['courir','courr'],
['cueillir','cueiller'],
['faire', 'fer'],
['mourir', 'mourr'],
['valoir', 'vaudr']
];

//
var irregular_future_conditional =
[
['aller', 'ir'],
['avoir', 'aur'],
['être', 'ser'],
['pleuvoir', 'pleuvr'],
['pouvoir', 'pourr'],
['vouloir', 'voudr'],
['falloir', 'faudr'],
['prévoir', 'prévoir']
];

function get_french_future_conditional_stem(verb)
{
  var i, stemch, verbtouse;

  for (i = 0; i < irregular_future_conditional.length; i++)
  {
    if (verb == irregular_future_conditional[i][0])
       return irregular_future_conditional[i][1];
  }

  for (i = 0; i < irregular_future_conditional_endings.length; i++)
  {
    if (verb.slice(-irregular_future_conditional_endings[i][0].length) == irregular_future_conditional_endings[i][0])
       return verb.slice(0, -irregular_future_conditional_endings[i][0].length) + irregular_future_conditional_endings[i][1];
  }

  stemch = is_stem_changing(verb);

  if (stemch[1])
     verbtouse = stemch[0];
  else
     verbtouse = verb;

  if (verbtouse.slice(-1) == 'e')
     verbtouse = verbtouse.slice(0, -1);

  return verbtouse;
}

function get_french_command(verb, indicative)
{
  var command;

  if (verb == 'avoir') 
  {
    return ['','aie','','ayons','ayez',''];
  }
  else if (verb == 'être')
  {
    return ['','sois','','soyons','soyez',''];
  }
  else if (verb == 'savoir')
  {
    return ['','sache','','sachons','sachez',''];
  }
  else if (verb == 'vouloir')
  {
    return ['','veuille','','voulons','veuillez',''];
  }
  else
  {
    command = ['', indicative[1], '', indicative[3], indicative[4], ''];
    if (command[1].slice(-2) == 'es')
       command[1] = command[1].slice(0, -1);
    else if (command[1] == 'vas')
       command[1] = 'va';

    return command;
  }
}

function get_french_present_participle(verb, indicative)
{ 
  if (verb == 'avoir')
     return 'ayant';
  else if (verb == 'être')
     return 'étant';
  else if (verb == 'savoir')
     return 'sachant';
  else
     return indicative[3].slice(0, -3) + 'ant';
}

function conjugate_french(verb)
{
  var indicative, subjunctive, imperfect, simple_past, imperfect_subjunctive;
  var command, future, conditional, stem, vec;
  var present_participle, past_participle;
  var i;

  vec = get_french_indicative_and_pp(verb);
  indicative = vec[0];
  past_participle = vec[1];

  imperfect = get_french_imperfect(verb, indicative);
  subjunctive = get_french_subjunctive(verb, indicative);

  vec = get_french_simple_past_and_imperfect_subjunctive(verb);
  simple_past = vec[0];
  imperfect_subjunctive = vec[1];

  stem = get_french_future_conditional_stem(verb);

  future = [stem + 'ai', stem + 'as', stem + 'a',
            stem + 'ons', stem + 'ez', stem + 'ont'];
  conditional = [stem + 'ais', stem + 'ais', stem + 'ait',
                 stem + 'ions', stem + 'iez', stem + 'aient'];

  command = get_french_command(verb, indicative);

  present_participle = get_french_present_participle(verb, indicative);

  // Destroy nonexistent tenses
  if (verb == 'falloir')
  {
    for (i = 0; i < 6; i++)
    if (i != 2)
    {
      indicative[i] = '';
      subjunctive[i] = '';
      imperfect[i] = '';
      simple_past[i] = '';
      future[i] = '';
      conditional[i] = '';
      command[i] = '';
      imperfect_subjunctive[i] = '';
    }
    present_participle = '';
  }

  if (verb == 'neiger' || verb == 'tonner')
  {
    for (i = 0; i < 6; i++)
    if (i != 2)
    {
      indicative[i] = '';
      subjunctive[i] = '';
      imperfect[i] = '';
      simple_past[i] = '';
      future[i] = '';
      conditional[i] = '';
      command[i] = '';
      imperfect_subjunctive[i] = '';
    }
  }

  if (verb == 'pleuvoir')
  {
    for (i = 0; i < 6; i++)
    if (i != 2 && i != 5)
    {
      indicative[i] = '';
      subjunctive[i] = '';
      imperfect[i] = '';
      simple_past[i] = '';
      future[i] = '';
      conditional[i] = '';
      command[i] = '';
      imperfect_subjunctive[i] = '';
    }
  }

  if (verb == 'pouvoir' || verb == 'faillir')
  {
    command = ['','','','','',''];
  }

  return [indicative, subjunctive, imperfect, simple_past, future, conditional, imperfect_subjunctive, command, present_participle, past_participle];
}

function report_on(message, list)
{
  var report = message + 'Suffixes: ';
  var ct = 0;
  var i, j;
 
  for (i = 0; i < list.length; i++)
  for (j = 0; j < list.length; j++)
  if (i != j)
  {
    if (list[i][0].length >= list[j][0].length &&
        list[i][0].slice(-list[j][0].length) == list[j][0])
    {
      if (j < i)
      {
        alert('Hidden suffix: ' + list[i][0] + ', ' + list[j][0]);
      }
      if (ct > 0)
         report = report + ';   ';
      report = report + list[i][0] + ', ' + list[j][0];
      ct++;
    }
  }
  if (report == message + 'Suffixes: ')
     report = message + ' No suffixes found.';
  alert(report);
}

function debug_report_on_containment()
{
  report_on('Present tense: ', irregular_present_endings);
  report_on('Simple past tense: ', simple_past_endings);
  report_on('Future/conditional tense: ', irregular_future_conditional_endings);
}
