//
// $Id: clickzillaLogger.js,v 1.8 2005/08/10 16:19:20 larsbrueckner Exp $
// 
// included by robofoxOverlay.js
// inits event listeners for logging
// 

// Robofox vars
var firstload=true;
var rf_state=false;
var rf_mode=true;

var rf_commands = new Array(); // List of commands
var rf_commandIndex = 0;       // idx current command

// Helpers to pass values to functions
// called with setTimeout()
var rf_appcontent = null;
var rf_currentDocument = null;
var rf_docLoaded = false;

// Browser command elements
var rf_rm_close;
var rf_rm_closeWindow;

//
//

dump("robofox.js load\n");
dump(window);dump("\n");
//dump(window.getElementById("id"));dump("\n");
dump(window.toString());
dump(this);
dump("\n");

//rf_cm_close = window.getElementById("cmd_close");
//rf_cm_closeWindow = window.getElementById("cmd_closeWindow");
//dump(rf_cm_close);
//dump("\n");

window.addEventListener("load", function() { initRobofoxListener(); }, true);

// This method is an eventlistener on the global navigator window
// purpose: add robofox event listeners to new browser tabs

function initRobofoxListener(evt) {
  //dump("robofox register listener\n");
  rf_appcontent = document.getElementById("appcontent");   // browser

  if(rf_appcontent){
    rf_appcontent.addEventListener("load", robofoxLoadListener, true);
    rf_appcontent.addEventListener("unload", robofoxUnloadListener, true);
  }
}

//
// Event listener on all tabs
// executed after page load is complete
//

function robofoxLoadListener(evt){
  
  //evil hack
  if (firstload) {
    //dump("firstload\n");
    firstload=false;
    return;
  }

  // get page object
  //dump("Robofox page load listener ");
  //dump("Mode :" + rf_mode + " Check " + rf_state +"\n");
  //dump("\n");

  if(rf_mode == false) {
    dump("Not in robot mode: do nothing.\n");
    return;
  }

  var myDocument = evt.originalTarget;  
  var myWindow = myDocument.contentWindow;

  if(rf_state == false) {
    // this is checked exactly once.
    //dump("Checking for robot mode\n");
    var myUrl = myDocument.URL;
    rf_state = true;
    //dump("URL is..." + myUrl + "\n");
    if ( myUrl.indexOf("robotscript") > 0 ){
      // Enter Robotmode
      //dump("Entering Robotmode\n");
      robofoxInit(myDocument);
      window.setInterval("robofoxStep();",1337+42); 
    } else {
      // Do not enter Robotmode
      //dump("Robomode turned of\n");
      rf_mode=false;
      return;
    }
  }
  // this implies robot mode is active
  // perform next step
  dump("In robot mode\n");

  //pass document to robofoxStep() 
  rf_currentDocument = myDocument;
  rf_docLoaded=true;
  //window.setInterval("robofoxStep();",5000);
}

function robofoxUnloadListener(evt){
  rf_docLoaded=false;
}

//
// Init + Command parsing
//

function robofoxInit(myDocument){
  dump("Robofox init\n");
  
  // .txt files are rendered as
  //  HTML
  //   HEAD
  //   BODY 
  //    PRE text 
  
  var pretag=myDocument.firstChild.lastChild.firstChild;
  //dump ("found tag " + pretag.nodeName + "\n");
  var myCommands = pretag.firstChild.nodeValue;
  //dump(myCommands);
  var commandLines = myCommands.split("\n");
  var i;
  for (i=0; i < commandLines.length; i++) {
    rf_parseCommand(commandLines[i],i+1);
  }
  rf_parseCommand("quit",i+1)
}

function rf_parseCommand(line,lineNumber){
  //dump(line + "\n");
  //dump(lineNumber+":");
  if (line == "") {
    //dump("empty\n");
    return;
  }
  if (line.indexOf("--") == 0){
    //dump("comment\n");
    return;
  }
  var parts = line.split(",");
  
  var command = new Object();
  command.line = line;
  command.lineNumber = lineNumber;

  command.options = parts;
  
  var myToken = parts[0];
  //dump (myToken + "\n");
  
  var myFunc = null;
  
  if(myToken == "url"){ myFunc = rc_url; }
  if(myToken == "nop"){ myFunc = rc_nop; }
  if(myToken == "dump") { myFunc = rc_dump; }
  if(myToken == "link") { myFunc = rc_link; }
  if(myToken == "quit") { myFunc = rc_quit; }
  if(myToken == "form") { myFunc = rc_form; }
  if(myToken == "submit") { myFunc = rc_submit; }

  if(myFunc == null) {
    //dump("ignored " + myToken + "\n");
    return;
  }
  
  command.func = myFunc;
  
  var idx = rf_commands.length;
  
  rf_commands[idx] = command;
  
}


//
// Actions
//

function robofoxStep(){
  dump("Robofox step " + rf_commandIndex + " ");
  if ( ! rf_docLoaded ) {
    dump("document not loaded, waiting ...\n");
    return;
  }
  var currentCommand = rf_commands[rf_commandIndex];
  rf_commandIndex++;
  dump("line: " + currentCommand.lineNumber + " " + currentCommand.line + "\n");
  var myDocument = rf_currentDocument;
  currentCommand.func(myDocument,currentCommand.options);
}

// robofox commands

// url jump to new absolute url
function rc_url(myDocument,cl){
  dump("url\n");
  var newurl = cl[1];
  myDocument.location.href=newurl;
}

// dump: print HTML of current website
// TODO: dump frames
function rc_dump(myDocument,cl){
  var bodyTag = myDocument.firstChild.lastChild;
  //dump(bodyTag.innerHTML);
  //dump(myDocument);
  rec_dump(myDocument);
  dump("\n");
  //window.setTimeout("robofoxStep();",1000);
}


function rc_nop(myDocument,cl){
  dump("nop\n");
  //window.setTimeout("robofoxStep();",1000);
}

function rc_link(myDocument, cl){
  dump("link\n");
  var myText = cl[1];
  //dump(myText);
  //dump("\n");

  var myLinks = getDocumentLinks(myDocument, myText);  

  if (myLinks.length == 0) {
    dump("Error: No suitable link found, skipping\n");
    //window.setTimeout("robofoxStep();",1000);
    return;
  }

  //dump("Found Links " + myLinks.length + "\n");
  
  //for (var i=0; i < myLinks.length; i++){
  //  dump(myLinks[i]);
  //  dump(" ");
  //  dump(myLinks[i].url);
  //  dump("\n");
  //  dump(myLinks[i].innerHTML);
  //  dump("\n");
  //}

  //dumpchildstruct(myLinks);

  //choose random link

  var randomLink = myLinks[randomIndex(myLinks.length)];
  dump("picked link: " + randomLink.innerHTML + "\n");

  //var randomElement = randomLink.reference;
  //dump(" " + randomElement + " " + randomElement.firstChild + "\n");
  //create event
  //var event = myDocument.createEvent("Events");
  //event.initEvent("click",false,true);
  //fire link 
  //randomElement.dispatchEvent(event);

  myDocument.location.href=randomLink.url;

  //window.setTimeout("robofoxStep();",1000);
}

function rc_form(myDocument,cl){
  var formName = cl[1];
  var myForm = findForm(myDocument,formName);

  if (myForm == null) {
    dump("Form "+formName+" not found, skipping\n");
    //window.setTimeout("robofoxStep();",1000);
    return
  }

  for ( var i = 2; i < cl.length; i++ ) {
    var command = "myForm."+cl[i]+";";
    eval(command);
  }
  //window.setTimeout("robofoxStep();",2000);
}


function rc_submit(myDocument,cl){
  dump("Submit\n");
  var myForm=findForm(myDocument,cl[1]);
  if (myForm == null) {
    dump("Form "+formName+" not found, skipping\n");
    //window.setTimeout("robofoxStep();",1000);
    return
  }
  myForm.submit();
  //form.btnG.click();
  //window.setTimeout("robofoxStep();",4000);
}

function rc_quit(myDocument,cl){
  dump("quitting\n");
  window.closeWindow(true);
}

// helpers

function rec_dump(myDocument){

  var bodyTag = myDocument.firstChild.lastChild;
  dump(bodyTag.innerHTML);

  if(myDocument.frames) {
    var length=myDocument.frames.length;
    for (i = 0; i < length; ++i)
      {
	var frame = myDocument.frames[i];
	rec_dump(frame);
      }
  }
} 

function dumpchildstruct(myElement){
  dump("struct\n");
  dumpchildstruct_real(myElement, "");
}

function dumpchildstruct_real(myElement, myPrefix){
  dump ( myPrefix + myElement + " " + myElement.id + 
	 " " + myElement.nodeName + "\n\n" );
  if (myElement.hasChildren) {
    var childPrefix = myPrefix + "   ";
    for (var i=0; i < myElement.childNodes.length; i++){
      dumpchildstruct_real(myElement.childNodes.item(i),childPrefix);
    }
  }
}

function dumpattributes(myElement){
}

// Following Code is
// from Moz.org P3P pageInfoOverlay.js

var gTopWin;
var gTopDoc;

function getDocumentLinks(myDocument,myText){
  var result = new Array();
  initTopDocAndWin();
  
  list = getLinksFor("a", "href", gTopWin, gTopDoc);
  for (var j = 0; j < list.length; j++)
  {
    var text = list[j].innerHTML;
    if (text.indexOf(myText)>-1){
      result.push(list[j]);
    }
  }
  return result;
}

function initTopDocAndWin(){
  gTopWin = window;
  gTopDoc = document.getElementById("appcontent");
}

function getLinksFor(aTagName, aAttrName, aWin, aDoc)
{
  var i, frame, length, list = new Array;

  // cycle through frames
  if (aWin)
  {
    length = aWin.frames.length;
    for (i = 0; i < length; ++i)
    {
      frame = aWin.frames[i];
      list = list.concat(getLinksFor(aTagName, aAttrName, 
                                     frame, frame.document));
    }
  }

  // now look for tags in the leaf document
  var elts = aDoc.getElementsByTagName(aTagName);
  length = elts.length;
  for (i = 0; i < length; ++i)
  {
    var element = new Object();
    element.url = elts[i][aAttrName];
    element.innerHTML = elts[i]["innerHTML"];
    element.reference = elts[i];
    list.push(element);
  }
  return list;
}

function findForm(element,formName){
  var result = null;
  if (element.nodeName) {
    //dump(element.nodeName + "\n");
    if (element.nodeName == "FORM") {
      dump("Form " + element.name + "\n");
      if (element.name) {
	if (element.name == formName) {
	      result = element;
	      dump("Found form " + formName + "\n");
	      return result;
	}
      }
    }
  }
  if (element.childNodes.length > 0) {
    for (var i=0; i < element.childNodes.length; i++) {
      var childResult = findForm(element.childNodes.item(i),formName);
      if (childResult != null) {
	return childResult;
      }
    }
  }
  // found nothing
  return null;
}
    

    

// return an int between 0 and max
function randomIndex(max) {
  return Math.floor(Math.random()*max);
}
