//=-- BreakoutRenderer.cpp - Output the HTML for a breakout... -----*- C++ -*-=
//
//  This class is used to output the HTML that corresponds to the tree-looking
//  breakout.  It tries to be flexible so that it can be useful for many 
//  purposes as such, however, the interface can be kind of confusing.  :)
//
//=---------------------------------------------------------------------------=
//  This file is copyright (c) 2000 Chris Lattner and stuff.
//=---------------------------------------------------------------------------=

#include "BreakoutRenderer.h"
#include "Table.h"
#include <string.h>  // For memset

int BreakoutRenderer::HasSuccessiveSibling(Tree::Iterator I, int Depth) const {
  I++;    // Skip current node...
  while (I) {
    int CurDepth = I->P;
    if (CurDepth < Depth) return 0;
    if (CurDepth == Depth) return 1;
    I++;
  }
  
  return 0;
}

int BreakoutRenderer::CalculateURLDepth(const String &URL) {
  int Depth = -1;    // Start off '/' at depth 0.
  int Count = URL.strchr('/');
//  if (URL.Length() == 0) return 0;

  while (Count != -1) {
    Depth++;
    Count = URL.strchr('/', Count+1);  // Count how many /'s are in the URL
  }

  if (!URL.nCompare("http://", 7))
    Depth -= 2;
  
  // Return +1 if the string didn't end in a /
  return (URL[URL.Length()-1] == '/') ? Depth : Depth + 1;
}

void BreakoutRenderer::OutputBreakout(const LinkedList<String> &Header,
                                      const Tree &TheTree, 
                                      const LinkedList<String> &ColSettings
                                      ) const {
  String ThemeURL = Descriptor.PluginSourceURL;
  int ColWidth = ColSettings.GetLength();

  if (Params.InTable("ImageURL"))
    ThemeURL = Params["ImageURL"]->GetStringValue();

  O << "<table cellspacing=0 cellpadding=0 border=0>\n";

  if (Header.GetLength() > 0) {
    LinkedList<String>::Iterator I  = Header.GetIterator();
    LinkedList<String>::Iterator Al = ColSettings.GetIterator();
    O << "<tr>\n  <TD valign=center " << *Al << "><b>" << *I << "</b></TD>\n";
    for (I++, Al++; I; I++, Al++) 
      O << "  <TD widht=5></TD><TD " << *Al << "><b>" << *I << "</b></td>\n";

    O << "</tr>\n";
  }

  O << "<tr>\n"
       "  <td colspan=" << ColWidth*2-1 << " bgcolor=#000000><img src='" 
    << ThemeURL << "/clear.gif' width=1 height=1"
    << " alt='------------------------------------------'></TD>\n</tr>\n";

  int Continuation[1000];
  memset(Continuation, 0, 1000);
  
  Tree::Iterator I = TheTree.GetIterator();
  for (; I; I++) {
    int Depth = I->P;
    const LinkedList<String> &Captions = I->S;
    LinkedList<String>::Iterator ColSets = ColSettings.GetIterator();
    
    O << "<tr>\n  <td valign=center " << *ColSets << ">";
    ColSets++;

    for (int i = 0; i < Depth; i++) {
      if (i == Depth-1) { // Try to do T or L nodes.
        Continuation[i] = HasSuccessiveSibling(I, Depth);
        if (Continuation[i])
          O << "<img src='" << ThemeURL << "/T.gif' align=top alt='|-'> ";
        else 
          O << "<img src='" << ThemeURL << "/L.gif' align=top alt='`-'> ";
      } else {
        if (Continuation[i])
          O << "<img src='" << ThemeURL << "/B.gif' align=top alt='|&nbsp;'>";
        else
          O << "<img src='" << ThemeURL << "/E.gif' align=top alt='&nbsp;&nbsp;'>";
      }
    }
    
    LinkedList<String>::Iterator CI = Captions.GetIterator();
    if (*CI) { O << *CI; CI++; }
    O << "</TD>\n"; 

    for (; CI; CI++, ColSets++)
      O << "  <TD WIDTH=5></TD>\n"
        << "  <TD " << *ColSets << ">" << *CI << "</td>\n";

    O << "</tr>\n";
  }
  O << "</table>\n";
}
