/*******************************************************************************<?php/*
 *
 * LEIDEN OPEN VARIATION DATABASE (LOVD)
 *
 * Created     : 2007-06-18
 * Modified    : 2014-09-24
 * Version     : 1.3
 * For LOVD    : 2.0-36
 *
 * Copyright   : 2004-2014 Leiden University Medical Center; http://www.LUMC.nl/
 * Programmers : Ing. Ivo F.A.C. Fokkema <I.F.A.C.Fokkema@LUMC.nl>
 *               Ir. Gerard C.P. Schaafsma <G.C.P.Schaafsma@LUMC.nl>
 * Last edited : Ing. Ivo F.A.C. Fokkema <I.F.A.C.Fokkema@LUMC.nl>
 *
 *
 * This file is part of LOVD.
 *
 * LOVD is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * LOVD is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LOVD; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *************/

class mutalyzer {
    function getInfo ()
    {
        return
             array(
                    'name' => 'LOVD Mutalyzer connection module',
                    'version' => '1.3',
                    'description' => 'LOVD module to connect to Mutalyzer to verify submitted variants with a reference sequence.',
                    'settings' =>
                             array(
                                    // 2010-08-23; 2.0-29; changed to Mutalyzer 2.0
                                    // 2014-09-17; 2.0-36; changed to new URLs of Mutalyzer 2.0.0.dev.
                                    'url' => 'https://mutalyzer.nl/',
                                    'url_version' => '2.0',
                                    'accessionid' => array(),
                                  ),
                  );
    }





    function checkUD ($sGene)
    {
        // Checks if this UD still exists in the Mutalyzer cache; if not, it will resubmit it.
        // Will do this once per gene per session max.
        global $_SETT;

        if (!empty($_SESSION['modules']['mutalyzer']['checkUD'][$sGene])) {
            return $_SESSION['modules']['mutalyzer']['checkUD'][$sGene];
        }

        // Does gene exist at all?
        if (!in_array($sGene, lovd_getGeneList())) {
            return false; // If asked for this gene again, will simply check again.
        }

        $_SESSION['modules']['mutalyzer']['checkUD'][$sGene] = 'in_progress'; // "Lock" temporarely.
        $aSett = $GLOBALS['_MODULES']->getSettings('mutalyzer');
        if (!empty($aSett['accessionid'][$sGene]['UD'])) {
            // Module knows an UD.
            $sUD = $aSett['accessionid'][$sGene]['UD'];

            // 2014-09-17; We can't use lovd_php_file() code anymore, since it can't deal with SSL.
            $aHeaders = @get_headers($aSett['url'] . 'Reference/' . $sUD . '.gb');
            if (!$aHeaders) { $aHeaders = array(); }
            foreach ($aHeaders as $sHeader) {
                if (substr($sHeader, 0, 5) == 'HTTP/') {
                    // HTTP header.
                    if (preg_match('/^HTTP\/1\.. 200 OK$/i', $sHeader)) {
                        $_SESSION['modules']['mutalyzer']['checkUD'][$sGene] = 1;
                        return true;
                    } else {
                        // Unsure what we got, for debugging purposes we will store it in the $_SESSION.
                        $_SESSION['modules']['mutalyzer']['checkUD'][$sGene] = $sHeader;
                        return false;
                    }
                }
            }
        }

        // If we're still here, it didn't work.
        $_SESSION['modules']['mutalyzer']['checkUD'][$sGene] = 0;

        @list($sFile) = mysql_fetch_row(mysql_query('SELECT genbank_uri FROM ' . TABLE_DBS . ' WHERE symbol = "' . mysql_real_escape_string($sGene) . '" AND genbank = 1'));
        if ($sFile && is_readable(ROOT_PATH . 'genbank/' . $sFile)) {
            // Get a new UD identifier from Mutalyzer.
            $sUD = $this->getUDfromMutalyzer($sFile);
            if ($sUD) {
                if ($sUD != $aSett['accessionid'][$sGene]['UD']) {
                    // Received a different UD!
                    $aSett['accessionid'][$sGene]['UD'] = $sUD;
                    $GLOBALS['_MODULES']->setSettings('mutalyzer', $aSett); // Store UD for the next run.
                }
                $_SESSION['modules']['mutalyzer']['checkUD'][$sGene] = 1;
                return true;
            }
        }
        return false;
    }




        
    function getUDfromMutalyzer ($sFile)
    {
        // Fetches the UD number after uploading a GenBank file to Mutalyzer (2.0)
        $aSett = $GLOBALS['_MODULES']->getSettings('mutalyzer');
        $sData = 'file=' . urlencode(file_get_contents(ROOT_PATH . 'genbank/' . $sFile));

        // Get data from Mutalyzer
        $sUD = implode(lovd_php_file('http://www.lovd.nl/mirrors/mutalyzer/uploadRefseqToMutalyzer.php?url=' . urlencode($aSett['url']), false, $sData));
        if ($sUD) {
            return $sUD;
        }
        return false;
    }





    function getTranscriptVersionFromMutalyzer ($sRefSeqGenomic, $sRefSeqTranscript)
    {
        // 2010-12-09; 2.0-30; Fetches Mutalyzer transcript version (e.g. DMD_v001)
        $aSett = $GLOBALS['_MODULES']->getSettings('mutalyzer');
        
        $aOutput = @lovd_php_file('http://www.lovd.nl/mirrors/mutalyzer/getTranscriptVariantFromMutalyzer.php?url=' . rawurlencode($aSett['url']) . '&genomicReference=' . $sRefSeqGenomic . '&transcriptReference=' . $sRefSeqTranscript);
        if ($aOutput && is_array($aOutput)) {
            return $aOutput[0];
        }
    }





    function enable ()
    {
        // Will be run when module is getting enabled.
        $aSett = $GLOBALS['_MODULES']->getSettings('mutalyzer');

        // Per gene, check if there is a genbank file that we can send to mutalyzer.
        // If so, send it and retrieve accessionnumber. This needs to be stored and used as a reference.
        $qGenes = mysql_query('SELECT symbol, genbank_uri, refseq_genomic, refseq_mrna FROM ' . TABLE_DBS . ' WHERE genbank != 0');
        while ($r = mysql_fetch_row($qGenes)) {
            // Send GenBank file.
            list($sSymbol, $sFile, $sRefSeqGenomic, $sRefSeqTranscript) = $r;

            if (is_readable(ROOT_PATH . 'genbank/' . $sFile)) {
                 // 2011-05-04; 2.0-32; Check if GenBank file is available
                 // this option is for those cases where genbank = 1
                 
                 if (empty($aSett['accessionid'][$sSymbol]['UD'])) {
                    // Get an UD identifier from Mutalyzer
                    // 2011-05-05; 2.0-32; Changed check, $aSett['accessionid'][$sSymbol]' was not enough, ['MutVer'] can have a value  
                    $sUD = $this->getUDfromMutalyzer($sFile);
                    if ($sUD) {
                        $aSett['accessionid'][$sSymbol]['UD'] = $sUD;
                    }
                }
            } elseif (!empty($sRefSeqGenomic) && substr($sRefSeqGenomic, 0, 3) != 'NC_') {
                // this option is for those cases where genbank = 2 (NCBI GenBank record)
                $aSett['accessionid'][$sSymbol]['UD'] = $sRefSeqGenomic;
            } elseif (!empty($sRefSeqGenomic) && substr($sFile, 0, 3) == 'UD_'){
                // this option is for those cases where genbank = 3 (Mutalyzer UD identifier 
                $aSett['accessionid'][$sSymbol]['UD'] = $sFile;
            }
                    
            if (!empty($aSett['accessionid'][$sSymbol]['UD'])) {
                // 2010-12-09; 2.0-30; add Mutalyzer transcript version to $aSett('accessionid'][$sSymbol]
                $sMutVersion = $this->getTranscriptVersionFromMutalyzer($sRefSeqGenomic, $sRefSeqTranscript);
                if (!$sMutVersion && !empty($sUD)) {
                    // 2011-04-05; 2.0-32; use UD number for older NG_ versions (when Mutalyzer uses a newer version)
                    // and for Mutalyzer UD identifiers
                    $sMutVersion = $this->getTranscriptVersionFromMutalyzer($sUD, $sRefSeqTranscript);
                    $sUD = null;
                }                        
                if ($sMutVersion) {
                    // 2011-04-05; 2.0-32; Now set $aSett['accessionid'][$sSymbol]['MutVer']
                    $aSett['accessionid'][$sSymbol]['MutVer'] = $sMutVersion;
                }
            }
        }
        $GLOBALS['_MODULES']->setSettings('mutalyzer', $aSett);
    }





    function processForm ($sForm, & $aForm)
    {
        // Process LOVD form data before it gets to the screen.
        if (in_array($sForm, array('SubmitVariantData', 'SubmitVariantsEdit'))) {
            $aSett = $GLOBALS['_MODULES']->getSettings('mutalyzer');
            $_CURRDB = mysql_fetch_assoc(mysql_query('SELECT * FROM ' . TABLE_DBS . ' WHERE symbol = "' . ($sForm == 'SubmitVariantData'? $_POST['gene'] : $_SESSION['currdb']) . '"'));
            $_CURRDB['symbol_short'] = substr($_CURRDB['symbol'], 0, strpos($_CURRDB['symbol'] . '_', '_'));

            // We only work, if we've got a reference sequence in the database.
            if (($_CURRDB['genbank'] == 1 && !empty($aSett['accessionid'][$_CURRDB['symbol']]) && !empty($_CURRDB['refseq_mrna'])) || ($_CURRDB['genbank'] > 1 && $_CURRDB['genbank_uri'])) {
                $aReturn = array();
                foreach ($aForm as $nItem => $aItem) {
                    // Line by line, go through the form.
                    if ($aItem[2] == 'Variant/DNA') {
                        // Add mutalyzer button.
                        $aReturn[] = $aItem;
                        // FIXME; we should somehow parse this output.
                        // 2011-02-16; 2.0-30b; Fixed bug when calling mutationName, the UD must now be retrieved from an array.
                        // (Ivo) There are actually more problems with this script. Implementing a quick fix: try different ways to link to Mutalyzer.
                        $sURL = '';
                        if (!empty($aSett['accessionid'][$_CURRDB['symbol']]['MutVer'])) {
                            $sURL = 'check?mutationName=';
                            // if ($aSett['accessionid'][$_CURRDB['symbol']]['UD']) {
                            if (!empty($aSett['accessionid'][$_CURRDB['symbol']]['UD'])) {
                                // 2011-05-05; 2.0-32; to prevent notices added ['UD']
                                // FIXME; MutVer has not been calculated using this file, so I'm not sure this is a good idea...
                                $sURL .= $aSett['accessionid'][$_CURRDB['symbol']]['UD'];
                            } else {
                                $sURL .= $_CURRDB['refseq_genomic'];
                            }
                            $sURL .= rawurlencode('(' . $aSett['accessionid'][$_CURRDB['symbol']]['MutVer'] . '):');
                        } else {
                            $sURL = 'getGS?variantRecord=' . $_CURRDB['refseq_mrna'] . '&forward=1&mutationName=' . ($_CURRDB['genbank'] == 1? $aSett['accessionid'][$_CURRDB['symbol']]['UD'] : $_CURRDB['genbank_uri']) . rawurlencode(':');
                        }
                        $aReturn[] = array('', 'print', '<BUTTON type="button" onclick="javascript:if (document.forms[0][\'Variant/DNA\'].value.length > 0) { lovd_openWindow(\'' . $aSett['url'] . $sURL . '\' + encodeURIComponent(document.forms[0][\'Variant/DNA\'].value), \'ModuleMutalyzerNamecheck\', 800, 400); } else { window.alert(\'Please fill in the DNA field.\'); } return false;">Check variant with Mutalyzer ' . $aSett['url_version'] . '</BUTTON>');
                    } else {
                        $aReturn[] = $aItem;
                    }
                }
                $aForm = $aReturn;
                return true;
            }
        }
        return false;
    }





    function upgrade ($sVersionOld)
    {
        // Run necessary code for upgrading this module.
        $aInfo = $this->getInfo();

        // Module version 0.8 has switched to Mutalyzer 2.0.
        if ($sVersionOld <= '0.7') {
            $GLOBALS['_MODULES']->setSettings('mutalyzer', 'url', $aInfo['settings']['url']);
            $GLOBALS['_MODULES']->setSettings('mutalyzer', 'url_version', $aInfo['settings']['url_version']);
            // Get the settings from TABLE_MODULES
            $aSett = $GLOBALS['_MODULES']->getSettings('mutalyzer');

            // Now see which genes have uploaded their own GenBank file
            // $qGenes = mysql_query('SELECT symbol, genbank_uri, refseq_genomic, refseq_mrna FROM ' . TABLE_DBS . ' WHERE genbank = 1');
            $qGenes = mysql_query('SELECT symbol, genbank_uri, refseq_genomic, refseq_mrna FROM ' . TABLE_DBS . ' WHERE genbank != 0');
            // Now for each gene, get a Mutalyzer 2 UD_ number
            while ($r = mysql_fetch_row($qGenes)) {
                // Send GenBank file.
                list($sSymbol, $sFile, $sRefSeqGenomic, $sRefSeqTranscript) = $r;
                if (empty($aSett['accessionid'][$sSymbol]['UD'])) {
                    $sUD = $this->getUDfromMutalyzer($sFile);
                    if ($sUD) {
                        $aSett['accessionid'][$sSymbol]['UD'] = $sUD;
                    } elseif (substr($sRefSeqGenomic, 0, 3) == 'NG_') {
                        // 2011-05-05; 2.0-32; Alternatively, use NG id here
                        // This way, the check in config_genes.php will work properly
                        $aSett['accessionid'][$sSymbol]['UD'] = $sRefSeqGenomic;
                    }
    
                    if (!empty($aSett['accessionid'][$sSymbol]['UD'])) {
                        // 2010-12-09; 2.0-30; add Mutalyzer transcript version to $aSett('accessionid'][$sSymbol]
                        $sMutVersion = $this->getTranscriptVersionFromMutalyzer($sRefSeqGenomic, $sRefSeqTranscript);
                        if (!$sMutVersion) {
                            // 2011-04-05; 2.0-32; use UD number for older NG_ versions (when Mutalyzer uses a newer version)
                            $sMutVersion = $this->getTranscriptVersionFromMutalyzer($sUD, $sRefSeqTranscript);
                        } else {
                            // 2011-04-05; 2.0-32; Now set $aSett['accessionid'][$sSymbol]['MutVer']
                            $aSett['accessionid'][$sSymbol]['MutVer'] = $sMutVersion;
                        }
                    }
                }
            }

        } elseif ($sVersionOld == '0.8') {
            // Get the settings from TABLE_MODULES
            $aSett = $GLOBALS['_MODULES']->getSettings('mutalyzer');

            // 2011-01-14; 2.0-30; structure of $aSett['accessionid'][$sSymbol] changed from string to array
            foreach ($aSett['accessionid'] as $sSymbol => $sUD) {
                $aSett['accessionid'][$sSymbol] = array('UD' => $sUD);
                //add Mutalyzer transcript version to $aSett('accessionid'][$sSymbol]
                $sQ = 'SELECT refseq_genomic, refseq_mrna FROM ' . TABLE_DBS . ' WHERE symbol="' . $sSymbol . '"';
                $q = mysql_query($sQ);
                while ($r = mysql_fetch_row($q)) {
                    list($sRefSeqGenomic, $sRefSeqTranscript) = $r;
                    $sMutVersion = $this->getTranscriptVersionFromMutalyzer($sRefSeqGenomic, $sRefSeqTranscript);
                    if ($sMutVersion) {
                        $aSett['accessionid'][$sSymbol]['MutVer'] = $sMutVersion;
                    }
                }
            }

        } elseif ($sVersionOld <= '1.2') {
            // 1.3 switched to a new URL schema.
            $GLOBALS['_MODULES']->setSettings('mutalyzer', 'url', $aInfo['settings']['url'], true);
            $GLOBALS['_MODULES']->setSettings('mutalyzer', 'url_version', $aInfo['settings']['url_version'], true);
        }
        // now also set the new settings
        // FIXME; Perhaps remove this, as it may create confusion, it may overwrite the settings we just changed.
        if (!empty($aSett)) {
            $GLOBALS['_MODULES']->setSettings('mutalyzer', $aSett);
        }
    }
}
