<?php
/*******************************************************************************
 *
 * LEIDEN OPEN VARIATION DATABASE (LOVD)
 *
 * Created     : 2007-06-27
 * Modified    : 2009-07-21
 * For LOVD    : 2.0-21
 *
 * Access      : Public
 * Purpose     : "My Submissions"; let submitters view their submissions; allow
 *               the public to view submitters' additions to the databases.
 *
 * Copyright   : 2004-2009 Leiden University Medical Center; http://www.LUMC.nl/
 * Programmer  : Ing. Ivo F.A.C. Fokkema <I.F.A.C.Fokkema@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
 *
 *************/

define('ROOT_PATH', './');
require ROOT_PATH . 'inc-init.php';

if (HAS_AUTH) {
    // If authorized, check for updates.
    require ROOT_PATH . 'inc-upgrade.php';
}

// Send them through when they want their own list (so they copy the URL correctly.
if (HAS_SUBS && !isset($_GET['submitterid'])) {
    header('Location: ' . PROTOCOL . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . '?submitterid=' . $_SUBS['submitterid'] . (isset($_GET['all_genes'])? '&all_genes' : ''));
    exit;
}

// 2008-09-17; 2.0-12; Column hiding also introduced in this variant overview.
if (isset($_COOKIE[$_SETT['cookie_id'] . '_hidden_cols'])) {
    $aHiddenColumns = explode(';', $_COOKIE[$_SETT['cookie_id'] . '_hidden_cols']);
} else {
    $aHiddenColumns = array();
}
if (!empty($_GET['hide_col'])) {
    if (is_array($_GET['hide_col'])) {
        foreach ($_GET['hide_col'] as $sCol) {
            // We don't check the availability of the column here, because some other gene may have it.
            if (!in_array($sCol, $aHiddenColumns)) {
                $aHiddenColumns[] = $sCol;
            }
        }
    } elseif (is_string($_GET['hide_col'])) {
        if (!in_array($_GET['hide_col'], $aHiddenColumns)) {
            $aHiddenColumns[] = $_GET['hide_col'];
        }
    }
}
if (!empty($_GET['show_col'])) {
    if (is_array($_GET['show_col'])) {
        foreach ($_GET['show_col'] as $sCol) {
            $nKey = array_search($sCol, $aHiddenColumns);
            if ($nKey !== false) {
                unset($aHiddenColumns[$nKey]);
            }
        }
    } elseif (is_string($_GET['show_col'])) {
        $nKey = array_search($_GET['show_col'], $aHiddenColumns);
        if ($nKey !== false) {
            unset($aHiddenColumns[$nKey]);
        } elseif ($_GET['show_col'] == 'all') {
            $aHiddenColumns = array();
        }
    }
}

// Now, store the settings in the cookie.
if ((!isset($_COOKIE[$_SETT['cookie_id'] . '_hidden_cols']) && count($aHiddenColumns)) || (isset($_COOKIE[$_SETT['cookie_id'] . '_hidden_cols']) && $_COOKIE[$_SETT['cookie_id'] . '_hidden_cols'] != $aHiddenColumns)) {
    setcookie($_SETT['cookie_id'] . '_hidden_cols', implode(';', $aHiddenColumns), time() + 60*60*24*31);
}

require ROOT_PATH . 'inc-top.php';
require ROOT_PATH . 'inc-lib-form.php';
if (HAS_SUBS && $_GET['submitterid'] == $_SUBS['submitterid']) {
    lovd_printHeader('submitters_my_submissions', 'LOVD - My Submissions');
} else {
    // Public, authorized users.
    lovd_printHeader('submitters_variants', 'LOVD - Variant listings per submitter');
}

// Deny access if not authorized and feature is turned off.
if (!HAS_AUTH && !$_CONF['my_submissions']) {
    lovd_showInfoTable('This feature is currently disabled by the LOVD settings. Please ask the LOVD manager to enable this feature.', 'stop');
    require ROOT_PATH . 'inc-bot.php';
    exit;
}





// Show form in all cases.
print('      To view all submissions done by a specific submitter, please fill in the numeric submitter ID.<BR>' . "\n" .
      '      <BR>' . "\n\n");

// Select current gene, at least.
if (empty($_GET['genes']) || !is_array($_GET['genes'])) {
    $_GET['genes'] = array();
    // 2008-11-27; 2.0-14; Added check on $_GET['all_genes'] to fix double listing of currently selected gene.
    if ($_SESSION['currdb'] && !isset($_GET['all_genes'])) {
        $_GET['genes'][] = $_SESSION['currdb'];
    }
}

// 2008-07-31; 2.0-10; Implement XSS check on search terms.
foreach ($_GET as $key => $val) {
    if (!is_array($val) && $val != strip_tags($val)) {
        $_GET[$key] = '';
    }
}

// Fetch genes.
$qGenes = mysql_query('SELECT symbol, gene FROM ' . TABLE_DBS . ' ORDER BY symbol');
$nGenes = mysql_num_rows($qGenes);

// Table.
// 2008-09-17; 2.0-12; Allow form to store info for hiding/showing columns.
print('      <FORM action="' . $_SERVER['PHP_SELF'] . '" method="get">' . "\n" .
      '        <INPUT type="hidden" name="order" value="' . (!empty($_GET['order'])? $_GET['order'] : '') . '">' . "\n" .
      '        <INPUT type="hidden" name="hide_col" value="">' . "\n" .
      '        <INPUT type="hidden" name="show_col" value="">' . "\n" .
      '        <TABLE border="0" cellpadding="0" cellspacing="1" width="950">' . "\n" .
      '          <TR>' . "\n" .
      '            <TD valign="top" rowspan="6" width="40%" style="padding-right : 10px;">' . "\n" .
      '              <B>Select gene(s) you wish to search in</B><BR>' . "\n" .
      '              <SELECT name="genes[]" size="' . ($nGenes > 5? 5 : $nGenes) . '" multiple>' . "\n");
while ($zGenes = mysql_fetch_assoc($qGenes)) {
    if (isset($_GET['all_genes'])) {
        $_GET['genes'][] = $zGenes['symbol'];
    }
    print('              <OPTION value="' . $zGenes['symbol'] . '"' . (in_array($zGenes['symbol'], $_GET['genes'])? ' selected' : '') . '>' . $zGenes['symbol'] . ' (' . lovd_shortenString($zGenes['gene'], 50) . ')</OPTION>' . "\n");
}
print('              </SELECT><BR>' . "\n" .
      '              <A href="#" onclick="var list = document.forms[0][\'genes[]\']; for (i=0;i<list.options.length;i++) { list.options[i].selected = true; }; return false">Select all</A>' . "\n" .
      '            </TD>' . "\n" .
      '            <TH colspan="2">Please fill in the numeric submitter ID or select the submitter</TH></TR>');

// 2008-11-11; 2.0-14; #34; Also show submitter dropdown list.
$qSubmitters = mysql_query('SELECT s.submitterid, CONCAT(c.country, " / ", s.city, " - ", s.firstname, " ", s.lastname) AS name FROM ' . TABLE_SUBS . ' AS s LEFT JOIN ' . TABLE_COUNTRIES . ' AS c ON (s.country = c.code) WHERE s.deleted = 0 ORDER BY name');
$sSelectSubmitter = '<SELECT name="submitter_select" onchange="document.forms[0].submitterid.value = this.value" style="width : 400px;">' . "\n" .
                    '                <OPTION value="" selected>-- select --</OPTION>';
while ($r = mysql_fetch_row($qSubmitters)) {
    $sSelectSubmitter .= "\n" .
                         '                <OPTION value="' . $r[0] . '"' . (!empty($_GET['submitterid']) && $_GET['submitterid'] == $r[0]? ' selected' : '') . '>' . $r[1] . '</OPTION>';
}
$sSelectSubmitter .= '</SELECT>';

// Array which will make up the form table.
$aForm = array(
                array('GET', '', '', '20%', '40%'),
                array('Submitter ID', 'text', 'submitterid', 10),
                array('Or select the name', 'print', $sSelectSubmitter),
                'skip',
                array('', 'submit', 'View submissions'),
                'skip',
              );
$_MODULES->processForm('SubmittersVariantsView', $aForm);
lovd_viewForm($aForm);

print('</TABLE></FORM><BR>' . "\n\n");

// That's it? Or do we need to search?
if (empty($_GET['submitterid']) || !count($_GET['genes'])) {
    // Can't search with this.
    require ROOT_PATH . 'inc-bot.php';
    exit;
}





// Show submitter info, first.
// 2008-11-25; 2.0-14; Added HAS_AUTH part; Authorized users should see deleted submitters, too.
$zData = mysql_fetch_assoc(mysql_query('SELECT s.*, c.country FROM ' . TABLE_SUBS . ' AS s LEFT OUTER JOIN ' . TABLE_COUNTRIES . ' AS c ON (s.country = c.code) WHERE s.submitterid = "' . $_GET['submitterid'] . '"' . (HAS_AUTH? '' : ' AND s.deleted = 0')));
if (!$zData) {
    // Wrong ID, apparently.
    lovd_showInfoTable('There is no submitter with that submitter ID.', 'stop');
    require ROOT_PATH . 'inc-bot.php';
    exit;
}

print('      <B class="S15">' . ucwords($zData['city']) . ', ' . $zData['country'] . '</B><BR>' . "\n" .
      '      <B>' . $zData['firstname'] . ' ' . $zData['lastname'] . '</B><BR>' . "\n" .
      '      ' . $zData['institute'] . '<BR>' . "\n" .
      '      ' . $zData['department'] . '<BR>' . "\n" .
      '      ' . str_replace(array("\r\n", "\r", "\n"), '<BR>', trim($zData['address'])) . '<BR>' . "\n" .
      '<BR>' . "\n\n");



// Fetch list of genes this submitter has patients in.
$qGenes = mysql_query('SELECT g.symbol FROM ' . TABLE_DBS . ' AS g LEFT JOIN ' . TABLE_PAT2VAR . ' AS p2v USING (symbol) LEFT JOIN ' . TABLE_PATIENTS . ' AS p USING (patientid) WHERE p.submitterid = "' . $_GET['submitterid'] . '" GROUP BY g.symbol');
$aGenes = array();
while (list($sSymbol) = mysql_fetch_row($qGenes)) {
    $aGenes[] = $sSymbol;
}

$nGenes = count($aGenes);   
if (!$nGenes) {
    lovd_showInfoTable('This submitter has not sent any submissions yet!', 'stop');
    require ROOT_PATH . 'inc-bot.php';
    exit;
}

// 2008-10-01; 2.0-13; Show "Unhide all columns" button.
if (count($aHiddenColumns)) {
    lovd_viewNavigation('<A href="#" onclick="document.forms[0].show_col.value=\'all\';document.forms[0].submit();">Unhide all columns</A>');
    print('      <BR>' . "\n\n");
}



// Per gene, show the variants connected to the patient owned by the submitter.
require ROOT_PATH . 'class/currdb.php';
foreach ($_GET['genes'] as $sSymbol) {
    // Shortcut; if requested gene is not in $aGenes, we're sure the submitter does not have any submissions here.
    if (!in_array($sSymbol, $aGenes)) {
        print('      ' . (HAS_SUBS && $_GET['submitterid'] == $_SUBS['submitterid']? 'You have' : 'The submitter has') . ' not sent any submissions to the ' . $sSymbol . ' gene database yet!<BR><BR>' . "\n\n");
        continue;
    }

    // 2008-08-28; 2.0-11; When "My Submissions" has been enabled, submitters can now also see their own unpublished variants.
    if (HAS_SUBS && $_GET['submitterid'] == $_SUBS['submitterid']) {
        $bCurator = true;
    } else {
        // Whether or not a user can see non-public data.
        $bCurator = lovd_isCurator($sSymbol);
    }

    $_CURRDB = new CurrDB(true, $sSymbol);
    $_CURRDB->hideCols('public', $bCurator);

    // Standard query, will be extended later on.
    $sQ = 'SELECT v.*, p.*, p2v.allele, p2v.status' . ($bCurator? ', stat.status_text AS status_' : '') . ', path.pathogenic_text AS pathogenic_, count(p2v_2.variantid) AS mutations, s.reference AS subs_reference FROM ' . TABLEPREFIX . '_' . $sSymbol . '_variants AS v LEFT JOIN ' . TABLE_PAT2VAR . ' AS p2v ON (p2v.symbol = "' . $sSymbol . '" AND v.variantid = p2v.variantid) LEFT JOIN ' . TABLE_PATIENTS . ' AS p USING (patientid) LEFT OUTER JOIN ' . TABLE_PAT2VAR . ' AS p2v_2 ON (p.patientid = p2v_2.patientid' . ($bCurator? '' : ' AND p2v_2.status >= ' . STATUS_MARKED) . ')' . ($bCurator? ' LEFT OUTER JOIN ' . TABLE_VAR_STATUS . ' AS stat ON (p2v.status = stat.status)' : '') . ' LEFT OUTER JOIN ' . TABLE_PATHOGENIC . ' AS path ON (p2v.pathogenic = path.pathogenic) LEFT OUTER JOIN ' . TABLE_SUBS . ' AS s ON (p.submitterid = s.submitterid) WHERE p.submitterid = "' . $_GET['submitterid'] . '" AND ' . ($bCurator? '1=1' : 'p2v.status >= ' . STATUS_MARKED . ' AND p2v_2.status >= ' . STATUS_MARKED);

    // Guess the column used to describe the mutation.
    $sMutationCol = $_CURRDB->getMutationCol();

    // Add p2v.allele here to show homozygous mutations twice in the list.
    $sQ .= ' GROUP BY v.variantid, p.patientid';

    $nResults = mysql_num_rows(mysql_query($sQ));

    // SORT: Current settings.
    if (isset($_GET['order']) && $_GET['order']) {
        $aOrder = explode(',', $_GET['order']);
    } else {
        $aOrder = array('', '');
    }

    // SORT: Column data.
    $aOrderList = array_merge(
             array('pathogenic_' => array('path.pathogenic', 'ASC')),
             array('sort' => array('v.sort', 'ASC')),
             $_CURRDB->buildOrderList());
    if ($bCurator) {
        // Add status.
        $aOrderList['status_'] = array('p2v.status', 'ASC');
    }
    if (!array_key_exists($aOrder[0], $aOrderList)) {
        // 2007-10-19; 2.0-01; Changed default sorting column from Exon to Variant/DNA.
        $aOrder[0] = $sMutationCol;
    }
    if ($aOrder[1] != 'ASC' && $aOrder[1] != 'DESC') {
        $aOrder[1] = $aOrderList[$aOrder[0]][1];
    }

    // 2007-10-19; 2.0-01; Fixed bug #18 - Variants do not sort correctly when selecting DNA column to sort on.
    // 2009-06-12; 2.0-19; Changed again, since the sort column now also contains the Exon information.
    // SORT: Additional sort columns (faking a perfect sort).
    $sOrderPre = '';
    $sOrderPost = '';
    if ($aOrder[0] == 'Variant/DNA') {
        // 1) In case of the mutation column, sort FIRST on sort.
        $sOrderPre .= 'v.sort ' . $aOrder[1] . ', ';
    } else {
        // 2) In case of anything else, sort on sort AFTER.
        $sOrderPost .= ', v.sort ' . $aOrder[1];
    }

    $sQ .= ' ORDER BY ' . $sOrderPre . $aOrderList[$aOrder[0]][0] . ' ' . $aOrder[1] . $sOrderPost . ', p.patientid';



    if (!$nResults) {
        // Searched, but no results.
        // We actually didn't check, if you're not a curator for all genes, if variants were public.
        print('      ' . (HAS_SUBS && $_GET['submitterid'] == $_SUBS['submitterid']? 'Your' : 'The submitter\'s') . ' variants in the ' . $sSymbol . ' gene are not public yet.<BR><BR>' . "\n\n");
        continue;
    }

    $q = mysql_query($sQ);
    if (!$q) {
        lovd_dbFout('SubmittersVariants', $sQ, mysql_error());
    }

    $n = (isset($nResults)? $nResults : $nTotal);
    print('      <SPAN class="S13"><B>' . $n . ($bCurator? '' : ' public') . ' entr' . ($n == 1? 'y' : 'ies') . ' in ' . $sSymbol . '</B></SPAN><BR>' . "\n");

    // Array which will make up the table (header and data).
    $aTable = array('pathogenic_' => array('Path.', 50));
    $aTable = array_merge($aTable, $_CURRDB->buildTable('list'));

    // Additional columns for authorized users.
    if ($bCurator) {
        $aTable['status_'] = array('Status', 75);
    }

    // Stretch it up, cause we're adding data to it...
    if ($aTable[$sMutationCol][1] < 200) {
        $aTable[$sMutationCol][1] = 200;
    }

    // Total width.
    $nTotalWidth = 2;
    $nHiddenColWidth = 5;
    foreach ($aTable as $sCol => $aCol) {
        // 2008-09-17; 2.0-12; Hidden columns are smaller!
        if (in_array($sCol, $aHiddenColumns) && $sCol != $sMutationCol) {
            // We don't allow the MutationCol to be hidden!
            $nTotalWidth += $nHiddenColWidth + 8;
        } else {
            $nTotalWidth += $aCol[1] + 8;
        }
    }



    // Stretch table up, to respect column widths.
    print('      <IMG src="' . ROOT_PATH . 'gfx/trans.png" alt="" width="' . $nTotalWidth . '" height="1"><BR>' . "\n\n");

    // Table.
    print('      <TABLE border="0" cellpadding="0" cellspacing="1" class="data">' . "\n" .
          '        <TR>');

    foreach ($aTable as $sField => $aCol) {
        // 2008-09-17; 2.0-12; Hide columns!
        if (in_array($sField, $aHiddenColumns) && $sField != $sMutationCol) {
            // We don't allow the MutationCol to be hidden!
            print("\n" . '          <TH width="' . $nHiddenColWidth . '"><A href="#" onclick="document.forms[0].show_col.value=\'' . $sField . '\';document.forms[0].submit();"><IMG src="' . ROOT_PATH . 'gfx/order_arrow_show.png" alt="Unhide ' . $aCol[0] . ' column" title="Unhide ' . $aCol[0] . ' column" width="5" height="13" border="0"></A></TH>');
            continue;
        }

        // Location onclick changed because of the search fields within the same <TH>. Clicking on the field triggers a sort.
        print("\n" . '          <TH valign="top"' . (!empty($aCol[2])? ' ' . $aCol[2] : '') . (is_numeric($aCol[1])? ' width="' . $aCol[1] . '"' : '') . (array_key_exists($sField, $aOrderList)? ' class="order' . ($aOrder[0] == $sField? 'ed' : '') . '"' : '') . '>' .
              (array_key_exists($sField, $aOrderList)? "\n" .
                                                           '            <TABLE border="0" cellpadding="0" cellspacing="0" width="100%" class="S11">' . "\n" .
                                                           '              <TR' . (array_key_exists($sField, $aOrderList)? ' onclick="document.forms[0].order.value=\'' . $sField . ',' . ($aOrder[0] == $sField? ($aOrder[1] == 'ASC'? 'DESC' : 'ASC') : $aOrderList[$sField][1]) . '\';document.forms[0].submit();"' : '') . '>' . "\n" .
                                                           '                <TH>' . str_replace(' ', '&nbsp;', $aCol[0]) . '</TH>' . "\n" .
                                                           '                <TD align="right" width="13">' . ($sField == $sMutationCol? '&nbsp;' : '<IMG src="' . ROOT_PATH . 'gfx/order_arrow_hide.png" alt="Hide ' . $aCol[0] . ' column" title="Hide ' . $aCol[0] . ' column" width="11" height="11" onclick="document.forms[0].hide_col.value=\'' . $sField . '\';document.forms[0].submit();" style="margin : 1px;">') . '</TD>' . "\n" .
                                                           '                <TD align="right" width="13"><IMG src="' . ROOT_PATH . 'gfx/order_arrow_desc' . ($aOrder[0] == $sField && $aOrder[1] == 'DESC'? '_sel' : '') . '.png" alt="Descending" title="Descending" width="13" height="6"><BR><IMG src="' . ROOT_PATH . 'gfx/order_arrow_asc' . ($aOrder[0] == $sField && $aOrder[1] == 'ASC'? '_sel' : '') . '.png" alt="Ascending" title="Ascending" width="13" height="6"></TD></TR>' .
                                                           '</TABLE>' : $aCol[0]) . '</TH>');
    }
    print('</TR>');

    $i = 0;
    $nRepeat = 25;
    while ($zData = mysql_fetch_assoc($q)) {
        // Print header repeatedly.
        $i ++;
        if (!($i%($nRepeat+1))) {
            print("\n" .
                  '        <TR>');
            foreach ($aTable as $sField => $aCol) {
                // 2008-09-17; 2.0-12; Hide columns!
                if (in_array($sField, $aHiddenColumns) && $sField != $sMutationCol) {
                    // We don't allow the MutationCol to be hidden!
                    print("\n" . '          <TH width="' . $nHiddenColWidth . '"><A href="#" onclick="document.forms[0].show_col.value=\'' . $sField . '\';document.forms[0].submit();"><IMG src="' . ROOT_PATH . 'gfx/order_arrow_show.png" alt="Unhide ' . $aCol[0] . ' column" title="Unhide ' . $aCol[0] . ' column" width="5" height="13" border="0"></A></TH>');
                    continue;
                }

                print("\n" . '          <TH valign="top"' . (!empty($aCol[2])? ' ' . $aCol[2] : '') . (is_numeric($aCol[1])? ' width="' . $aCol[1] . '"' : '') . (array_key_exists($sField, $aOrderList)? ' class="order' . ($aOrder[0] == $sField? 'ed' : '') . '"' : '') . '>' .
                      (array_key_exists($sField, $aOrderList)? "\n" .
                                                                   '            <TABLE border="0" cellpadding="0" cellspacing="0" width="100%" class="S11">' . "\n" .
                                                                   '              <TR' . (array_key_exists($sField, $aOrderList)? ' onclick="document.forms[0].order.value=\'' . $sField . ',' . ($aOrder[0] == $sField? ($aOrder[1] == 'ASC'? 'DESC' : 'ASC') : $aOrderList[$sField][1]) . '\';document.forms[0].submit();"' : '') . '>' . "\n" .
                                                                   '                <TH>' . str_replace(' ', '&nbsp;', $aCol[0]) . '</TH>' . "\n" .
                                                                   '                <TD align="right" width="13">' . ($sField == $sMutationCol? '&nbsp;' : '<IMG src="' . ROOT_PATH . 'gfx/order_arrow_hide.png" alt="Hide ' . $aCol[0] . ' column" title="Hide ' . $aCol[0] . ' column" width="11" height="11" onclick="document.forms[0].hide_col.value=\'' . $sField . '\';document.forms[0].submit();" style="margin : 1px;">') . '</TD>' . "\n" .
                                                                   '                <TD align="right" width="13"><IMG src="' . ROOT_PATH . 'gfx/order_arrow_desc' . ($aOrder[0] == $sField && $aOrder[1] == 'DESC'? '_sel' : '') . '.png" alt="Descending" title="Descending" width="13" height="6"><BR><IMG src="' . ROOT_PATH . 'gfx/order_arrow_asc' . ($aOrder[0] == $sField && $aOrder[1] == 'ASC'? '_sel' : '') . '.png" alt="Ascending" title="Ascending" width="13" height="6"></TD></TR>' .
                                                                   '</TABLE>' : $aCol[0]) . '</TH>');
            }
            print('</TR>');
            $i = 1;
        }

        print("\n" .
              '        <TR valign="top"' . ($bCurator && $zData['status'] < STATUS_OK? ' class="' . ($zData['status'] < STATUS_MARKED? 'del' : 'marked') . '"' : '') . ' style="cursor : pointer; cursor : hand;" onmouseover="this.className = \'' . ($bCurator && $zData['status'] < STATUS_OK? ($zData['status'] < STATUS_MARKED? 'del_' : 'marked_') : '') . 'hover\';" onmouseout="this.className = \'' . ($bCurator && $zData['status'] < STATUS_OK? ($zData['status'] < STATUS_MARKED? 'del' : 'marked') : '') . '\';" onclick="window.location.href = \'' . lovd_cleanDirName(dirname($_SERVER['PHP_SELF']) . '/' . ROOT_PATH) . 'variants.php?select_db=' . $sSymbol . '&amp;action=view&amp;view=' . $zData['patientid'] . '%2C' . $zData['variantid'] . '%2C' . $zData['allele'] . lovd_showSID(true, true) . '\';">');

        // Create normal anchor link as well.
        $sLink = '<A href="' . ROOT_PATH . 'variants.php?select_db=' . $sSymbol . '&amp;action=view&amp;view=' . $zData['patientid'] . '%2C' . $zData['variantid'] . '%2C' . $zData['allele'] . lovd_showSID(true, true) . '" class="data"' . ($zData['status'] < STATUS_MARKED? ' style="color : #AAAAAA;"' : '') . '>';
        if ($sMutationCol) {
            $zData[$sMutationCol] = $sLink . $zData[$sMutationCol] . '</A>';
        }

        // Very unlikely not to function; only if none of the HGVS standard DNA, RNA or Protein fields are enabled, this will fail.
        if ($zData['mutations'] > 1) {
            // 2008-03-27; 2.0-05; Show only a maximum number of other mutations associated with this patient. Otherwise, hide them all.
            if ($zData['mutations'] > 10) {
                // Too many to fetch; wouldn't look good.
                // FIXME; make a setting out of this.
                $zData[$sMutationCol] .= '<BR>&nbsp;&nbsp;&nbsp;&nbsp;+ ' . ($zData['mutations'] - 1) . ' others';
            } else {
                // Fetch info on other mutations.
                // FIXME; this may be quite a performance lag with a high $_GET['limit'] value and lots of associated mutations.
                // Backwards compatible with MySQL 4.0 and earlier; if we rely on MySQL 4.1, we could do a GROUP_CONCAT in top mutation fetch query that save us these queries.
                $sQOther = 'SELECT p2v.*, v.`' . $sMutationCol . '` FROM ' . TABLE_PAT2VAR . ' AS p2v LEFT OUTER JOIN ' . TABLEPREFIX . '_' . $sSymbol . '_variants AS v ON (p2v.symbol = "' . $sSymbol . '" AND v.variantid = p2v.variantid) WHERE ' . ($bCurator? '' : 'p2v.status >= ' . STATUS_MARKED . ' AND ') . 'p2v.patientid = "' . $zData['patientid'] . '" AND !(p2v.symbol = "' . $sSymbol . '" AND v.variantid = "' . $zData['variantid'] . '" AND p2v.allele = "' . $zData['allele'] . '") ORDER BY v.sort ASC';

                $qOther = mysql_query($sQOther);
                $sOther = '';
                $aOther = array();

                // Loop other variants found in the same patient.
                while ($zOther = mysql_fetch_assoc($qOther)) {
                    if ($zOther['symbol'] == $sSymbol) {
                        // Other variant in same gene.
                        $sOther .= ($sOther? ', ' : '') . $zOther[$sMutationCol];
                    } else {
                        // Other variant in different gene.
                        if (!isset($aOther[$zOther['symbol']])) {
                            $aOther[$zOther['symbol']] = 0;
                        }
                        $aOther[$zOther['symbol']] ++;
                    }
                }

                if (count($aOther)) {
                    foreach ($aOther as $sGene => $nOther) {
                        $sOther .= ($sOther? ', ' : '') . $sGene . ' (' . $nOther . ')';
                    }
                }

                $zData[$sMutationCol] .= '<BR>&nbsp;&nbsp;&nbsp;&nbsp;+ ' . $sOther;
            }
        }

        // Parse and build Custom Links.
        lovd_buildLinks($zData);

        // Transform select lists' values.
        $_CURRDB->transformSelectValues($zData);

        // FIXME;
        // Shorten strings for TEXT that surely doesn't contain HTML tags... HOW?

        // Submitter reference...
        if ($_CURRDB->colExists('Patient/Reference') && $zData['subs_reference']) {
            // 2008-03-28; 2.0-05; Show full submitter information directly from this link.
            $zData['Patient/Reference'] .= (!empty($zData['Patient/Reference'])? ', ' : '') . '<A href="#" onclick="lovd_openWindow(\'' . ROOT_PATH . 'submitters.php?action=view&amp;view=' . $zData['submitterid'] . lovd_showSID(true, true) . '\', \'SubmitterView\', 400, 175, event.screenX - 50, event.screenY - 50); return false;">' . $zData['subs_reference'] . '</A>';
        }

        foreach ($aTable as $sField => $aCol) {
            // 2008-09-17; 2.0-12; Hidden columns are smaller!
            if (in_array($sField, $aHiddenColumns) && $sField != $sMutationCol) {
                // We don't allow the MutationCol to be hidden!
                print("\n" . '          <TD width="' . $nHiddenColWidth . '">&nbsp;</TD>');
                continue;
            }

            print("\n" . '          <TD' . (!empty($aCol[2])? ' ' . $aCol[2] : '') . (is_numeric($aCol[1])? ' width="' . $aCol[1] . '"' : '') . ($aOrder[0] == $sField? ' class="ordered"' : '') . '>' . (!$zData[$sField]? '-' : $zData[$sField]) . '</TD>');
        }
        print('</TR>');
    }
    print('</TABLE><BR>' . "\n\n");
}

require ROOT_PATH . 'inc-bot.php';
exit;
?>