<?php

// -------------------------------------------------------------------------------------------------
require_once("class_SidebarBuilder.php");

// -------------------------------------------------------------------------------------------------
class Listopia extends ListopiaUser // extends ListopiaAuth // extends ListopiaCore
{ 
  // -----------------------------------------------------------------------------------------------
  protected $SideBarBuilders = array(
    SideBarItem::Welcome                => 'SidebarBuilder::Welcome',
    SideBarItem::AddToList              => 'SidebarBuilder::AddToList',
    SideBarItem::BasicListNavigator     => 'SidebarBuilder::BasicListNavigator',
    SideBarItem::AdvancedListNavigator  => 'SidebarBuilder::AdvancedListNavigator',
    SideBarItem::Profile                => 'SidebarBuilder::Profile',
    SideBarItem::Messages               => 'SidebarBuilder::Messages',
    SideBarItem::MiniStats              => 'SidebarBuilder::MiniStats',
    SideBarItem::NewListInstructions    => 'SidebarBuilder::NewListInstructions',
    SideBarItem::NewUserInstructions    => 'SidebarBuilder::NewUserInstructions',
    SideBarItem::PublicDisplayStub      => 'SidebarBuilder::PublicDisplayStub',
    );
  
  // -----------------------------------------------------------------------------------------------
  private static function getTitleForSideBarItem($item)
  {
    switch( $item )
    {
      case SideBarItem::Welcome:                return "Hello"; 
      case SideBarItem::AddToList:              return "Add";
      case SideBarItem::BasicListNavigator:     return "Lists";
      case SideBarItem::AdvancedListNavigator:  return "Lists";
      case SideBarItem::Profile:                return "Stuff"; 
      case SideBarItem::Messages:               return "Messages"; 
      case SideBarItem::MiniStats:              return "Stats"; 
      case SideBarItem::NewListInstructions:    return "How It Works"; 
      case SideBarItem::NewUserInstructions:    return "Do It";
      case SideBarItem::PublicDisplayStub:      return "List Rules";
    }
    
    die("[getTitleForSideBarItem] unknown SideBarItem type");
  }
  
  


  // -----------------------------------------------------------------------------------------------
  // standard boilerplate that heads every page; loads standard styling and configures the head block
  public function unloggedInPage()
  {
    $verSuffix = __VERSUFFIX__;
  ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--[if lt IE 7 ]><html class="ie ie6" xmlns="http://www.w3.org/1999/xhtml" lang="en"> <![endif]-->
<!--[if IE 7 ]><html class="ie ie7" xmlns="http://www.w3.org/1999/xhtml" lang="en"> <![endif]-->
<!--[if IE 8 ]><html class="ie ie8" xmlns="http://www.w3.org/1999/xhtml" lang="en"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <!--<![endif]-->
  
<head profile="http://gmpg.org/xfn/11">

  <title>Baby You Really Wanna Get In Here</title>

  <!-- metadata --> 
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

  <!-- css --> 
  <link rel="stylesheet" href="css/base.min.css<?=$verSuffix?>" />
  <link rel="stylesheet" href="css/skeleton.css<?=$verSuffix?>" />
  <link rel="stylesheet" href="css/layout.css<?=$verSuffix?>" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.css" />

  <script type="text/javascript" src="js/listopia.js<?=$verSuffix?>"></script>

  <!--[if lt IE 9]>
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->

</head>
<body>
  <div class="container">

    <div class="row">
      <div class="one-third column lst-options" style="margin-top: 48px; text-align:center;"></div>
      <div class="one-third column lst-options" style="margin-top: 48px; text-align:center;">
        <br>
        <h4>HORSE AIDS</h4>
        <h4>AWARENESS NETWORK</h4>
        <img src="images/hoss.gif" width=300 height=224 />
        <img src="images/linebreak.gif" width=234 height=32 />
      </div>
    </div>


    <div class="row">

      <div class="one-third column lst-options" style="margin-top: 48px; text-align:center;">

        <img src="images/fe_old.jpg" width=300 style="margin-bottom: 24px; border: 4px solid black;" />

        <button id="UILogin" style="width:250px">I COME PRE-APPROVED AND LEAKING</button>

      </div>

      <div class="one-third column lst-options" style="margin-top: 48px; text-align:center;">
        THANK YOU FOR YOUR PATIENTS<br><br><br>
        They were delicious<br><br><br>
        I see you baby, throttling that swan. Throttling that swan. Throttling that swan. I see you baby, throttling that swan. GET YOU SWAN THROTTLING HANDS OFF ME<br><br>

      </div>

      <div class="one-third column lst-options" style="margin-top: 48px; text-align:center;">

        <img src="images/fe_new.jpg" width=300 style="margin-bottom: 24px; border: 4px solid black;" />

        <button id="UIApply" style="width:250px">OOF! MY FOMO, YO YO MA</button>

      </div>
    </div>

  </div>

  <div id="UILoginDialog" title="&nbsp;" style="display:none">
      <form id="SignIn" action="">
        <label for="AuthUser">Username</label><input spellcheck="false" autocapitalize="off" autocorrect="off" autocomplete="off" type="text" id="AuthUser" />
        <label for="AuthPwd">Password</label><input type="password" id="AuthPwd" />
        <div id="Reason" style="font-size:0.8em; color:red;"></div>
      </form>
    </div>  


  <div id="UIApplyDialog" title="&nbsp;" style="display:none">
      <form id="Apply" action="">
        <div>
        We will need a working email address (no temporary shit, this process may take days for us to notice and respond to), the user/pass you would like - note we have literally <strong>no</strong> security here so don't use your gmail password fer crissakes - and then tell us why you want to join. Be creative! Or just type 200 swear words. We're easily pleased.<br><br>
        <h6>(This address won't actually be stored on the site, don't fret)</h6>
        <label for="MyEmail">Contact Email</label><input style="width:400px !important" spellcheck="false" autocapitalize="off" autocorrect="off" autocomplete="off" type="text" id="MyEmail" />
        <label for="MyUser">Desired Username</label><input style="width:400px !important" maxlength="16" spellcheck="false" autocapitalize="off" autocorrect="off" autocomplete="off" type="text" id="MyUser" />
        <label for="AuthPwd">Desired Password</label><input style="width:400px !important" type="password" id="AuthPwd" />
        <label for="MessageBox">Cover Letter</label><textarea style="width:400px !important" cols="60" rows="5" id="MessageBox" ></textarea>
        <div id="Reason" style="font-size:0.8em; color:blue;"></div>
        </div>
      </form>
    </div>


  <!-- JS -->
  <script
    src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"
    integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
    crossorigin="anonymous"></script>
  <script
    src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"
    integrity="sha256-xNjb53/rY+WmG+4L6tTl9m6PpqknWZvRt0rO1SRnJzw="
    crossorigin="anonymous"></script>

</body>
  
  <script type="text/javascript">
  $(function()
  {
    $('#UILogin').click(function(){
      $('#UILoginDialog').dialog('open');
      return false;
    });
    $('#UIHelp').click(function(){
      $('#UIHelpDialog').dialog('open');
      return false;
    });
    $('#UIApply').click(function(){
      $('#UIApplyDialog').dialog('open');
      return false;
    });

    $('#UILogout').click(function(){
      $.get("php/ajax_authLogout.php").complete(function() { location.reload(); });
      return false;
    });

    $('#UILoginDialog').dialog({
      autoOpen: false,
      modal: true,
      resizable: false,
      width: 250,
      buttons: {
        "Submit": function(event) 
        {
          var authDialog = $(this);
          var authReason = $("#SignIn #Reason");
          
          $(event.target).attr("disabled", true).addClass("ui-state-disabled");
          authReason.html("<img style='margin:0px auto' src='images/ajax-loader.gif' alt=''/>");
          
          $.post(
            "php/ajax_authLogin.php", 
            { user: $("#SignIn #AuthUser").val(), pass: $("#SignIn #AuthPwd").val() },
            function(data) 
            { 
              if (data.success)
              {
                location.reload();
              }
              else
              {
                authReason.html(data["reason"]);
                $(event.target).attr("disabled", false).removeClass("ui-state-disabled");
              }
            },
            "json");
        }
      }
    });

    $('#UIHelpDialog').dialog({
      autoOpen: false,
      modal: true,
      resizable: false,
      width: 450,
      buttons: {
        "Submit": function(event) 
        {
          var authReason = $("#Help #Reason");

          $(event.target).attr("disabled", true).addClass("ui-state-disabled");

          var str1 = "HELP: ";
              str1 = str1.concat( $("#Help #MyEmail").val() );
              str1 = str1.concat( " ---- " );
              str1 = str1.concat( $("#Help #MessageBox").val() );

          $.post(
            "php/ajax_secmsg.php", 
            { 
              blob: B64.encode( str1 )
            },
            function(data) 
            { 
              authReason.html(data["result"]);

            },
            "json");
        }
      }
    });

    $('#UIApplyDialog').dialog({
      autoOpen: false,
      modal: true,
      resizable: false,
      width: 450,
      buttons: {
        "Submit": function(event) 
        {
          var authReason = $("#Apply #Reason");

          $(event.target).attr("disabled", true).addClass("ui-state-disabled");

          var str1 = "APPLICATION: ";
              str1 = str1.concat( $("#Apply #MyEmail").val() );
              str1 = str1.concat( " ---- " );
              str1 = str1.concat( $("#Apply #MyUser").val() );
              str1 = str1.concat( " ---- " );
              str1 = str1.concat( $("#Apply #AuthPwd").val() );
              str1 = str1.concat( " ---- " );
              str1 = str1.concat( $("#Apply #MessageBox").val() );

          $.post(
            "php/ajax_secmsg.php", 
            { 
              blob: B64.encode( str1 )
            },
            function(data) 
            { 
              authReason.html(data["result"]);

            },
            "json");
        }
      }
    });

  });

  </script>

</html>

  <?php
  }



  // -----------------------------------------------------------------------------------------------
  // standard boilerplate that heads every page; loads standard styling and configures the head block
  public function pageBegin($pageTitle, $pageDesc="", $extraScripts=array())
  {
    $verSuffix = __VERSUFFIX__;
  ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--[if lt IE 7 ]><html class="ie ie6" xmlns="http://www.w3.org/1999/xhtml" lang="en"> <![endif]-->
<!--[if IE 7 ]><html class="ie ie7" xmlns="http://www.w3.org/1999/xhtml" lang="en"> <![endif]-->
<!--[if IE 8 ]><html class="ie ie8" xmlns="http://www.w3.org/1999/xhtml" lang="en"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--><html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <!--<![endif]-->
  
<head profile="http://gmpg.org/xfn/11">

  <title><?php echo $pageTitle; ?></title>

  <!-- metadata --> 
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta name="description" content="<?php echo $pageDesc ?>" />
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

  <!-- css --> 
  <link rel="stylesheet" href="css/base.min.css<?=$verSuffix?>" />
  <link rel="stylesheet" href="css/skeleton.css<?=$verSuffix?>" />
  <link rel="stylesheet" href="css/layout.css<?=$verSuffix?>" />
  <link rel="stylesheet" href="css/listopia.css<?=$verSuffix?>" />
  <link rel="stylesheet" href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" />

  <!--[if lt IE 9]>
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->

  <!-- icons --> 
  <link rel="shortcut icon" href="images/favicon.ico" />
  <link rel="apple-touch-icon" href="images/apple-touch-icon.png" />
  <link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png" />
  <link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png" />
  <link rel="apple-touch-icon" sizes="144x144" href="images/apple-touch-icon-144x144.png" />

  <!-- js --> 
  <script type="text/javascript" src="js/listopia.js<?=$verSuffix?>"></script>
  <script type="text/javascript">
  if (document.images) {
      img1 = new Image();
      img1.src = "images/ajax-loader-fb.gif";
  }
  </script>

  
  <?php
  foreach ($extraScripts as &$scr)
    printf("  <script type='text/javascript' src='$scr%s'></script>\n", __VERSUFFIX__);
  
  print("  </head>\n");
  print("<body>\n");
  }
  

  // -----------------------------------------------------------------------------------------------
  // go dig through list 1199 - Listopia Sloganeering - for a suitable motto
  // grab random data from a user-editable location, what could possibly go hideously wrong
  private function getMottoFromSloganeeringList()
  {
    $query = $this->ldb->select(array(
                              'fields' => 'item_blurb, item_id',
                              'table' => 't_items',
                              'condition' => 'item_list = 1199 and LENGTH(item_blurb) < 110 and item_rejected = "n" and (item_votesup - item_votesdown) >= 2'
                              ));
                              
    if (empty($query[0])) 
    {
      return "Home of Broken Database Queries";
    }
    
    $randomEntry = mt_rand(0, count($query) - 1);
    $randomMotto = $query[$randomEntry];

    $entryID = $randomMotto['t_items']['item_id'];
    
    return "<a style='color:black' href='/list.php?id=1199#entry_$entryID'>" . stripslashes($randomMotto['t_items']['item_blurb']) . "</a>";
  }

  private function getTitleFromTitleList()
  {
    $query = $this->ldb->select(array(
                              'fields' => 'item_blurb, item_id',
                              'table' => 't_items',
                              'condition' => 'item_list = 3171 and LENGTH(item_blurb) >= 8 and item_rejected = "n" and (item_votesup - item_votesdown) >= 0'
                              ));
                              
    if (empty($query[0])) 
    {
      return "BUGGERED";
    }
    
    $randomEntry = mt_rand(0, count($query) - 1);
    $randomMotto = $query[$randomEntry];

    $entryID = $randomMotto['t_items']['item_id'];
    
    return "<a style='color:black' href='/list.php?id=3171#entry_$entryID'>" . stripslashes($randomMotto['t_items']['item_blurb']) . "</a>";
  }


  
  private $contentsTerminator = "";
  
  // -----------------------------------------------------------------------------------------------
  public function contentsBeginWithSidebar($sidebarItems, $title, $subtitle, $inGuestMode = false)
  {
    if (count($sidebarItems) < 1)
      die("[contentsBeginSidebar] cannot handle empty sidebar items array");
      
    $titleText = $this->getTitleFromTitleList();
    $titleSub = $this->getMottoFromSloganeeringList();

    if ( $inGuestMode === TRUE )
    {
      $titleText = "LISTOPIA";
      $titleSub = "Viewing as guest";
    }

  ?>
  <div class="container">

    <div class="one-third column lst-options" style="margin-top: 24px;">

      <div class="lst-fixnav">
      <h1 class="lst-title"><?=$titleText?></h1>
      <p id="motto" class="lst-motto"><?=$titleSub?></p>
      
      <ul class="tabs">
  <?php
    
    // active tab is the first one, by default
    $defaultActiveTab = $sidebarItems[0];
    
    // default tab can be specified by enum index via the URL, eg. ?tab=3
    if (isset($_GET['tab']) && 
        is_numeric($_GET['tab']))
    {
      // get the integer value to use from the _GET table
      $tabFromGET = intval( $_GET['tab'] );
      
      // make sure we have that tab available, otherwise we just leave it as default
      if (in_array($tabFromGET, $sidebarItems))
        $defaultActiveTab = $tabFromGET;
    }
    
    // build the tab list
    foreach ($sidebarItems as &$value) 
    {
      printf("      <li><a onclick='' href='#%sTab' %s>", 
        Listopia::getTitleForSideBarItem($value),
        (($value === $defaultActiveTab) ? "class='active'" : ""));
        
      print(Listopia::getTitleForSideBarItem($value));
      
      print("</a></li>\n");
    }
  ?>
      </ul>
      
      <ul class="tabs-content">      
  <?php
    foreach ($sidebarItems as &$value) 
    {
      print("      <li id='" . Listopia::getTitleForSideBarItem($value) . "Tab' " . (($value === $defaultActiveTab) ? "class='active'" : "") . ">\n");
      
      call_user_func($this->SideBarBuilders[$value], $this );
      
      print("      </li>\n\n");
    }
  ?>
      </ul>


    </div>
    </div>
    
    <div class="two-thirds column">
      <a name="PageContent" style="margin-top: 24px;">&nbsp;</a>
      <img src="images/linebreak.gif" width=234 height=32 class="lst-divider"/>
      
      <h2><?=$title?></h2>
      <p class="lst-subtitle"><span id="ui-subtitle-bar" style="width: 90%;display: inline-block;"><?=$subtitle?></span></p>
      
  <?php
    $this->contentsTerminator = "    </div> <!-- rhs column -->\n";
  }
  
  // -----------------------------------------------------------------------------------------------
  public function contentsBeginSinglePage($title, $subtitle)
  {
  ?>
  <div class="container">
    <div class="one-third column" style="margin-top: 24px;">
      <h1 class="lst-title"><a href="index.php">REDACTED</a></h1>
    </div>
    
    <div class="two-thirds column">
      <a name="PageContent" style="margin-top: 24px;">&nbsp;</a>
      <img src="images/linebreak.gif" width='234' height='32' alt='divider' class="lst-divider"/>
      
      <h2><?=$title?></h2>
      <p class="lst-subtitle"><?=$subtitle?></p>
    </div>
    
  </div> <!-- container -->
    
  <div class="container" style="margin-top: 24px;">
  <?php
    $this->contentsTerminator = "";
  }

  // -----------------------------------------------------------------------------------------------
  public function contentsEnd()
  {
    echo $this->contentsTerminator;
    $this->contentsTerminator = "";
    
  ?>
  </div> <!-- container -->
  <?php  
  }
  
  // -----------------------------------------------------------------------------------------------
  // called after the main content to initiate JS loading; broken out so that per-page scripts
  // can be injected afterwards, but before the pageEnd() call
  public function pageEndScripts()
  {
    if ($this->isLoggedIn())
    {
      $news = $this->ldb->select(array(
                          'table' => 'news',
                          'order' => 'timestamp_utc desc',
                          'limit' => 1
                          ));
      if ( !empty($news) ){
        $nquery = $news[0];
        if (!empty($nquery))
        {
          if ($nquery['news']['timestamp_utc'] > Session::getInstance()->gl_unix_last_login)
          {
            if (!isset(Session::getInstance()->gl_shown_news_alert))
            {
              $newNews = $nquery;
              Session::getInstance()->gl_shown_news_alert = true;
            }
          }
        }
      }
    }
  ?>

<!-- JS -->
  <script
    src="https://code.jquery.com/jquery-1.12.4.min.js"
    integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
    crossorigin="anonymous"></script>
  <script
    src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"
    integrity="sha256-xNjb53/rY+WmG+4L6tTl9m6PpqknWZvRt0rO1SRnJzw="
    crossorigin="anonymous"></script>
    
<script type="text/javascript" src="js/tabs.js"></script>
<script type="text/javascript" >
  
RewireTheFuckingButtons();

</script>
  <?php
  }

  // -----------------------------------------------------------------------------------------------
  // close the body, tie off the page
  public function pageEnd()
  {
  ?>
</body>
</html>  
  <?php
  }
  
  // -----------------------------------------------------------------------------------------------
  function generateDiscussionCommentHTML($comment, $inGuestMode = false)
  {
    $cmtAuthorLink = ProfileLink($comment['t_discussion']['disc_user'], '#PageContent');
    
    // if the comment was in the last 24 hrs, print the H:M info too
    $unixDate = strtotime($comment['t_discussion']['disc_datetime']);
    if ($unixDate < strtotime("24 hours ago"))
      $cmtDate = date("F j, Y", $unixDate);
    else
      $cmtDate = date("F j, Y, g:i a", $unixDate);
    
    $commentMessage = ConditionCommentForDisplay($this->Database(), $comment['t_discussion']['disc_comment']);
    
  
    $htm  = "<div class='lst-comments lst-comment-entry'><!-- " . $comment['t_discussion']['disc_id'] . " -->";
    $htm .= "<p>".  $commentMessage ."</p>";
    if ($inGuestMode === FALSE)
    {
    $htm .= sprintf("<code>%s by <a %s>%s</a></code>", $cmtDate, $cmtAuthorLink, $comment['t_discussion']['disc_username']);
  }
    $htm .= "</div>";
    
    return $htm;
  }
  
  // -----------------------------------------------------------------------------------------------
  function generateListEntriesHTML($theListID, $entries, $entryComments, $listData, $showingRejects=false, $inGuestMode=false)
  {
    $loggedIn = $this->isLoggedIn();
    $sesh = Session::getInstance();
    $listCreatedByCurrentUser = ($listData['t_lists']['list_createdby'] === $sesh->gl_userid);
    
    $mainHTML = "";
    $entryNum = 0;
    
    foreach ($entries as &$entry)
    {
      $entryNum ++;
      
      $isImagePost = ($entry['t_items']['item_extra'] == 'image');
      $posterProfileLink = ProfileLink($entry['t_items']['item_createdby'], '#PageContent');
      $wasMadeByCurrentUser = $loggedIn && ($entry['t_items']['item_createdby'] === $sesh->gl_userid);
      
      $voteUp = sprintf("%02d", intval( $entry['t_items']['item_votesup'] ));
      $voteDown = sprintf("%02d", intval( $entry['t_items']['item_votesdown'] ));
      
      if ($isImagePost)
        $postContent = stripslashes($entry['t_items']['item_blurb']);
      else
        $postContent = ConditionTextForDisplay($entry['t_items']['item_blurb']);

      // should we let loose the goose? or get regal wid th' eagle?
      $voteScore = intval($entry[0]['vote_score']);
      $masterDivClass = 'lst-entry';
      if ($voteScore <= -15)
        $masterDivClass .= ' crowmageddon';
      else if ($voteScore <= -10)
        $masterDivClass .= ' tragedy-eagle';
      else if ($voteScore <= -4)
        $masterDivClass .= ' harsh-goose';
      else if ($voteScore <= -2)
        $masterDivClass .= ' opacity-50';
      else if ($voteScore <= -1)
        $masterDivClass .= ' opacity-75';

      $entryID = $entry['t_items']['item_id'];

       if ( $theListID == 2975 )
       {
         $postContent = str_replace( "-", "<img src='/images/horseaids.gif'/>", $postContent );
         $postContent .= " HORSE AIDS <img src='/images/horseaids.gif'/>";
         $masterDivClass .= ' tragedy-horse';
       }
       if (  $entryID == 132745 || $entryID == 132979 )
       {
         $masterDivClass .= ' tragedy-horse';
       }

      // process comments upfront
      $commentCount = 'No';
      $commentText = 'Comments';

      if ( array_key_exists($entryID, $entryComments))
      {
        $entryDisc = $entryComments[$entryID];
        if (isset($entryDisc))
        {
          $commentCount = count($entryDisc);
        }
        if ($commentCount == 1)
          $commentText = 'Comment';
      }

      // recolour for new items
      if ($loggedIn)
      {
        $entryCreatedUnix = strtotime($entry['t_items']['item_created']);

        // created today
        if ($entryCreatedUnix > (strtotime("24 hours ago")))
          $masterDivClass .= ' lst-entry-today';
        // created since you last logged in
        else if ($sesh->gl_unix_last_login < $entryCreatedUnix)
          $masterDivClass .= ' lst-entry-lastlogin';
        
        $commentsClass = "";
        $commentPrefix = "";
        if ($commentCount != 'No')
        {
          $lastCommentUnix = strtotime($entryDisc[intval($commentCount)-1]['t_discussion']['disc_datetime']);
          if ($sesh->gl_unix_last_login < $lastCommentUnix)
          {
            $commentsClass = "class='lst-comment-lastlogin'";
            $commentPrefix = "<img src='images/chat-icon-yes-greyed.png' style='vertical-align: text-bottom; padding-right: 4px;'/>";
          }
          else
          {
            
          }
        }
      }
      
      // fade out the inoperable thumb-vote buttons if the entry belongs to us
      $thumbButtonClass = "button thumb-button" . ($wasMadeByCurrentUser ? " thumb-button-own" : "");
      
      $contentPrefix = "<p title='#$entryNum'>";
      $contentSuffix = "</p>";
      
      if (($listCreatedByCurrentUser || $this->isAdminUser()))
      {
        if ($showingRejects)
        {
          $rejectionCode = "<a class='button thumb-button' onclick='list_UNRejectItem(this, $entryID); return false;' style='float:right; margin-top: 4px;'><img src='images/reject_item.png' width=14 height=15/></a>";
        }
        else
        {
          $rejectionCode = "<a class='button thumb-button' onclick='list_RejectItem(this, $entryID); return false;' style='float:right; margin-top: 4px;'><img src='images/reject_item.png' width=14 height=15/></a>";
        }
      }
      else
        $rejectionCode = "";

      $linkToPoster = "<div class='lst-post-author'><a " . $posterProfileLink . ">- " . $entry['users']['user_name'] . "</a></div>";

      if ( $inGuestMode === TRUE )
      {
        $linkToPoster = "<div class='lst-post-author' style='font-size:0.75em;color:darkorange;'>". $entry['t_items']['item_created'] . "</div>";
      }

      
      if ($isImagePost)
      {
      /* emergency image editing button!
        if ($this->isAdminUser())
        {
          $mainHTML .= "<p style='float:left'><img onclick='var ent = $(\"#e_$entryID\").get(0); $(ent).show(); simulatedClick(ent);' class='lst-ui-edit-item' src='images/edit_item.png'/><span class='edit_list_entry' id='e_$entryID' style='display:none'>";
          $mainHTML .= $postContent;
          $mainHTML .= "</span></p>";
        }
        */
$mainHTML .= <<<HTML
        <div class='$masterDivClass'><div>
          <a id='entry_$entryID' name='entry_$entryID'></a>
          {$rejectionCode}
          <img title='#$entryNum' style='margin:4px auto 4px auto;' class='ui-corner-all lst-avatar-img' src='{$postContent}'/>
          $linkToPoster
HTML;
      }
      else
      {
        // are we in the grace period? or are we a superuser? then add post-edit tags that get captured later
        if (($wasMadeByCurrentUser && $entryCreatedUnix > strtotime(LS_GRACE_PERIOD)) || $this->isAdminUser())
        {
          $contentPrefix = "<p><img onclick='simulatedClick($(\"#e_$entryID\").get(0));' class='lst-ui-edit-item' src='images/edit_item.png'/><span class='edit_list_entry' id='e_$entryID'>";
          $contentSuffix = "</span></p>"; // <p class='lst-edit-help'>[ click post to edit ]</p>
        }
        

$mainHTML .= <<<HTML
        <div class='$masterDivClass'><div>
          <a id='entry_$entryID' name='entry_$entryID'></a>
          {$rejectionCode}
          {$contentPrefix}{$postContent}{$contentSuffix}
          $linkToPoster
HTML;
      }
      
      if ($loggedIn && $inGuestMode === FALSE)
      {
        $thumbDownOnClick = (!$wasMadeByCurrentUser) ? " onclick='list_HandleVote(this, false, $entryID); return false;'" : "";
        $thumbUpOnClick   = (!$wasMadeByCurrentUser) ? " onclick='list_HandleVote(this, true, $entryID); return false;'" : "";
        
$mainHTML .= <<<HTML
        <div class='thumb-down'>
          <a class='$thumbButtonClass' $thumbDownOnClick ><img src='images/thumb-dn.png' width=14 height=15/><span id='vote-down-num-$entryID'>$voteDown</span></a>
        </div>
        
        <div class='thumb-up'>
          <a class='$thumbButtonClass' $thumbUpOnClick ><span id='vote-up-num-$entryID'>$voteUp</span><img src='images/thumb-up.png' width=14 height=15/></a>
        </div>
HTML;

      }
        
$mainHTML .= <<<HTML
        <code><a tabindex='0' $commentsClass style='cursor:pointer;' onclick='$(this.parentNode.parentNode.parentNode).next().toggle("blind");'>
        $commentPrefix $commentCount $commentText
        </a></code>
HTML;
      if ($showingRejects)
      {
        $rejectReason = stripslashes($entry['t_items']['item_rejected_reason']);
        $mainHTML .= "<p class='lst-rejected'>{$rejectReason}</p>";
      }

$mainHTML .= <<<HTML
      </div></div>
      
      <div class='lst-comment-pile-entries'>
      <div id='lst-comment-replacable-$entryID'>
HTML;

      if ($commentCount > 0)
      {
        foreach ($entryDisc as &$comment)
        {
          $mainHTML .= $this->generateDiscussionCommentHTML($comment, $inGuestMode);
        }
      }
      $mainHTML .= "</div>"; // close lst-comment-replacable- before the add-new-comment stuff
      
      if ($loggedIn && $inGuestMode === FALSE)
      {
        // encode the cookie auth key in there as a tiny bit of spam protection (we check it in the ajax php)
        $cookieCodeStamp = $_COOKIE[__LAUTH_KEY__];
        if (!isset($cookieCodeStamp))
          die("No cookie key? At this point? Smashing.");      
          
        $mainHTML .= "<div class='lst-comments lst-comment-addbox ui-corner-bottom' style='padding:8px'>";
        $mainHTML .= $this->UI_Misc()->GenTextEntryString("addComment", LS_COMMENT_ADD_BUTTON, 500);
        $mainHTML .= "<a tabindex='0' onclick='list_AddComment(this, $entryID, 0, $entryID, \"$cookieCodeStamp\"); return false' style='cursor:pointer;' class='full-width button'>Add</a>";
        $mainHTML .= "</div>";
      }

      $mainHTML .= "</div>"; // lst-comment-pile-entries
    }
    
    return $mainHTML;
  }

  // -----------------------------------------------------------------------------------------------
  function GetGenericSearches()
  {
    return array(
      'latest' => array(
        "Latest Entries",
        "Who done the what last",
        function(ListopiaDB $db, $dbLimit)
        {
          return $db->select(array(
            'fields' => 't_lists.list_headline, t_lists.list_id, t_lists.list_standfirst, t_lists.list_type ,t_lists.list_updated as factoid',
            'table' => 't_lists',
            'order' => 't_lists.list_updated desc',
            'condition' => DBQ_CONDITION_PUBLIC_LIST,
            'limit' => $dbLimit
            ));
        }
      ),
      'newest' => array(
        "Newest",
        "Hot new inventions from our scientists",
        function(ListopiaDB $db, $dbLimit)
        {
          return $db->select(array(
            'fields' => 't_lists.list_headline, t_lists.list_id, t_lists.list_standfirst, t_lists.list_type ,t_lists.list_created as factoid',
            'table' => 't_lists',
            'order' => 't_lists.list_created desc',
            'condition' => DBQ_CONDITION_PUBLIC_LIST,
            'limit' => $dbLimit
            ));
        }
      ),      
      'subscribed' => array( 
        "Most Subscribed",
        "The lists that have the most unique posters",
        function(ListopiaDB $db, $dbLimit)
        {
          return $db->select(array(
            'fields' => 'count(distinct(t_items.item_createdby)) as factoid, t_items.item_list, t_lists.list_headline, t_lists.list_id, t_lists.list_standfirst, t_lists.list_type',
            'table' => 't_items',
            'join' => 't_lists on t_lists.list_id = t_items.item_list',
            'group' => 't_items.item_list',
            'order' => 'factoid desc',
            'condition' => DBQ_CONDITION_PUBLIC_LIST,
            'limit' => $dbLimit
            ));
        }
      ),
      'largest' => array( 
        "Most Bulbous",
        "Who ate all the posts",
        function(ListopiaDB $db, $dbLimit)
        {
          return $db->select(array(
            'fields' => 'count(*) as factoid, t_lists.list_headline, t_lists.list_id, t_lists.list_standfirst, t_lists.list_type',
            'table' => 't_items',
            'join' => 't_lists on t_lists.list_id = t_items.item_list',
            'group' => 't_items.item_list',
            'order' => 'factoid desc',
            'condition' => DBQ_CONDITION_PUBLIC_LIST,
            'limit' => $dbLimit
            ));
        }
      ),
      'thumbposts' => array( 
        "Boiling Thumb Activity",
        "The toppiest thumberings per post",
        function(ListopiaDB $db, $dbLimit)
        {
          return $db->select(array(
            'fields' => '((sum(t_items.item_votesup + t_items.item_votesdown)) / (count(*) + 1)) as factoid, t_lists.list_headline, t_lists.list_id, t_lists.list_standfirst, t_lists.list_type',
            'table' => 't_items',
            'join' => 't_lists on t_lists.list_id = t_items.item_list',
            'group' => 't_items.item_list',
            'order' => 'factoid desc',
            'condition' => DBQ_CONDITION_PUBLIC_LIST,
            'limit' => $dbLimit
            ));
        }
      ),
      'topthumbs' => array( 
        "You Got Burned",
        "Look at all those thumb-downs",
        function(ListopiaDB $db, $dbLimit)
        {
          return $db->select(array(
            'fields' => 'sum(t_items.item_votesdown) as factoid, t_lists.list_headline, t_lists.list_id, t_lists.list_standfirst, t_lists.list_type',
            'table' => 't_items',
            'join' => 't_lists on t_lists.list_id = t_items.item_list',
            'group' => 't_items.item_list',
            'order' => 'factoid desc',
            'condition' => DBQ_CONDITION_PUBLIC_LIST,
            'limit' => $dbLimit
            ));
        }
      ),
      'debated' => array( 
        "Hotly Contested",
        "Commented right to the tits",
        function(ListopiaDB $db, $dbLimit)
        {
          return $db->select(array(
            'fields' => 'count(t_discussion.disc_item) as factoid, t_lists.list_headline, t_lists.list_id, t_lists.list_standfirst, t_lists.list_type',
            'table' => 't_discussion, t_items, t_lists',
            'group' => 't_items.item_list',
            'order' => 'factoid desc',
            'condition' => DBQ_CONDITION_PUBLIC_LIST . ' and t_discussion.disc_item != -1 and t_discussion.disc_item = t_items.item_id and t_items.item_list = t_lists.list_id',
            'limit' => $dbLimit
            ));
        }
      ),
      'listvote' => array( 
        "Community Service",
        "Voted well skill by our users",
        function(ListopiaDB $db, $dbLimit)
        {
          return $db->select(array(
            'fields' => 'sum(listvotes.vote) as factoid, t_lists.list_headline, t_lists.list_id, t_lists.list_standfirst, t_lists.list_type',
            'table' => 'listvotes, t_lists',
            'group' => 'listvotes.list',
            'order' => 'factoid desc',
            'condition' => DBQ_CONDITION_PUBLIC_LIST . ' and listvotes.list = t_lists.list_id',
            'limit' => $dbLimit
            ));
        }
      ),      
      'random' => array( 
        "I Just Can't Decide",
        "Spin the wheel of randomisation",
        function(ListopiaDB $db, $dbLimit)
        {
          return $db->select(array(
            'fields' => 't_lists.list_headline, t_lists.list_id, t_lists.list_standfirst, t_lists.list_type',
            'table' => 't_lists',
            'order' => 'rand()',
            'condition' => DBQ_CONDITION_PUBLIC_LIST,
            'limit' => $dbLimit
            ));
        }
      )      
    );
  }
  
  
  // -----------------------------------------------------------------------------------------------
  // this is a singleton class, access via getInstance
  protected static $instance;
  public static function getInstance()
  {
    if ( !isset(self::$instance))
    {
      FB::info("[Listopia] singleton instance");
      self::$instance = new self;
      self::$instance->init();
    }
    return self::$instance;
  }
  // -----------------------------------------------------------------------------------------------
}
?>