//the settings for these objects
pplPerSide = 9;
imagePath = "http://blog.beliefnet.com/godometer/images/meter/";
selectedCand = "";
var d = new Date()

//calculates today
today = "";
if ((d.getMonth()+1) < 10)
  today += "0"+ (d.getMonth()+1) +"/";
else
  today += (d.getMonth()+1) +"/";
if (d.getDate() < 10)
  today += "0"+ d.getDate() +"/"+ d.getFullYear();
else
  today += d.getDate() +"/"+ d.getFullYear();

  
//*********************************************************************************************
//holds All Information about a candidate
//*********************************************************************************************

//Object For Creating ID Numbers
function IDGen()
{
  unqNum = 0;
  
  this.getID = function()
  {
    rtnID = ""+ unqNum;
    while (rtnID.length < 5)
        rtnID = "0" + rtnID;
    unqNum++;
    return rtnID;
  }
}
IDNum = new IDGen();

//stores the Information for one candidate
function candatateTemplate()
{
  
  this.ID = IDNum.getID();
  this.Position = "";
  this.Name = "Unknown";
  this.PostId = "unknown";
  this.Rating = new Array;
  this.Date = new Array;
  this.PostTitle = "";
  this.Post = "";
  this.FullPost = "";
  this.Party = "";
  this.Link = "";
  this.PostLink = "";
  this.Display = "";
  this.BigDispNum = "";
  
  this.RatingIndex = 0;
  
  this.addRating = function(newRating)
  {
    if (this.BigDispNum == "")
      this.BigDispNum = newRating;
      
    switch (true)
    {
      case (newRating > 10):
        this.Rating.push(10);
      break;

      case (newRating < 0):
        this.Rating.push(0);
      break;
      
      default:
        this.Rating.push(newRating);
      break;
    }
  }
  
  //gets the next rating number in the series
  this.getNextRating = function(curPlace)
  {
    rtnTxt = "";
    if (curPlace != undefined)
    {
      if (curPlace < (this.Rating.length-1))
        rtnTxt = this.Rating[curPlace+1]
    }
    else
    {
      this.RatingIndex++;
      if (this.Rating.length > this.RatingIndex)
        rtnTxt = this.Rating[this.RatingIndex];
    }
    return rtnTxt;
  }
  
  //returns the party code for the candidate
  this.PartyCode = function()
  {
    rtnCd = "I";
    if (this.Party.search(/^dem/i) > -1)
      rtnCd = "D";
    else if (this.Party.search(/^rep/i) > -1)
      rtnCd = "R";
    return rtnCd;
  }
  
  //if updated today then stared
  this.stared = function()
  {
    if (this.Date[0] == today)
      return "_new_";
    else
      return "";
  }
  
  //creates a filename safe version of the name
  this.smallFace = function()
  {
    rtnName = this.Name.toLowerCase().replace(/ /g,"_");
    return imagePath +"face_"+ rtnName.replace(/\W/g,"") +".png";
  }

  //creates the selected version
  this.selectFace = function()
  {
    rtnName = this.Name.toLowerCase().replace(/ /g,"_");
    return imagePath +"face_"+ rtnName.replace(/\W/g,"") +"_sel.png";
  }
  
  //creates a filename safe version of the name
  this.bigFace = function()
  {
    rtnName = this.Name.toLowerCase().replace(/ /g,"_");
    return imagePath +"face_"+ rtnName.replace(/\W/g,"") +"_big.png";
  }
  
  //returns the main meter image for this
  this.getMeter = function()
  {
    //determins if the meter is moving up or down
    switch (true)
    {
      case (this.Rating.length < 2):
        dirMark = "";
      break;
      
      case (this.Rating[0] < this.Rating[1]):
        dirMark = "_down";
      break;

      case (this.Rating[0] > this.Rating[1]):
        dirMark = "_up";
      break;

      default:
        dirMark = "";
      break;
    }
    return imagePath +"meter_"+ this.PartyCode() +"_"+ this.BigDispNum + dirMark +".gif";
  }
  
  //displays the element in the main area
  this.select = function()
  {
    //if something is already selected then unselect it
    if (selectedCand != "")
      selectedCand.unselect();
      
    //changes to the correct main meter
    dispArea = document.getElementById("meter");
    if (dispArea != null)
      setBackground(dispArea,this.getMeter());

    //changes to the correct big head
    dispArea = document.getElementById("bigHead");
    if (dispArea != null)
      setBackground(dispArea,this.bigFace());

    //changes the background to the selected version
    setBackground(this.Display,this.selectFace());
    
    //if a post area is present then change the post area contents
    dispArea = document.getElementById("post");
    if (dispArea != null)
    {
      this.generatePost();
      
      //if there is a post by this guy on the page then hide it
      if (document.getElementById(this.PostId) != null)
        document.getElementById(this.PostId).style.display = "none";
    }

    //set this as the selected element
    selectedCand = this;
  }
  
  //unselects the element
  this.unselect = function()
  {
    setBackground(this.Display,this.smallFace());

    //if there is a post by this guy on the page then show it
    if (document.getElementById(this.PostId) != null)
      document.getElementById(this.PostId).style.display = "";
  }
  
  //builds and displays the entry
  this.createContainer = function(posNum)
  {
    this.Position = posNum;
    this.Display = document.createElement("li");
    this.Display.id = this.ID;
    this.Display.innerHTML = this.Rating[0];
    this.Display.onmouseover = function(){faceOver(this);};
    this.Display.onmouseout = function(){faceOut(this);};
    this.Display.onclick = function(){faceClick(this);};
    this.Display.className = "subMeter"+ this.PartyCode() + this.Position;
    
    //adds it to the interface
    this.unselect();
    this.displayNew();
    adList = document.getElementById("subMeters"+this.PartyCode());
    if (adList != null)
      adList.appendChild(this.Display);
  }

  //displays the new Icon if necessary
  this.displayNew = function()
  {
    //creates the new notification area
    tmpNewA = document.createElement("li");
    tmpNewA.id = "new"+ this.ID;
    tmpNewA.className = "newMarks"+ this.PartyCode() + this.Position;
    if (document.getElementById("newMarks"+this.PartyCode()))
      document.getElementById("newMarks"+this.PartyCode()).appendChild(tmpNewA);

    if (this.Date[0] == today)
      setBackground(document.getElementById("new"+this.ID),imagePath +"new_"+ this.PartyCode() +".png");
    else
      if (document.getElementById("new"+this.ID))
      document.getElementById("new"+this.ID).style.background = "";
  }
  
  //generates the popup content
  this.generatePopup = function()
  {
    retTxt = "";
    retTxt += "<div id='popupName'>"+ this.Name +"</div><div id='popupDate'>"+ this.Date[0] +"</div>";
    retTxt += "<div id='popupReading'><b>Currently:</b> "+ this.Rating[0];
    if (this.Rating.length > 1)
      retTxt += " &nbsp;&nbsp;&nbsp;<b>Previously:</b> "+ this.getNextRating(0);
    retTxt += "</div>";
    retTxt += "<div id='popupPost'>\""+ this.PostTitle +"\"</div>";
    
    return fixText(retTxt);
  }

  //generates the post content
  this.generatePost = function()
  {
    setBackground(document.getElementById("post"),imagePath +"post_background_"+ this.PartyCode() +".jpg");

    lblDate = new Date(this.Date[0]);
    lblTxt = (lblDate.getMonth()+1) +"/"+ lblDate.getDate() +"/";
    tmpYr = ""+lblDate.getFullYear();
    lblTxt += tmpYr.substring(2);

    document.getElementById("postDate").innerHTML = lblTxt;
    if (this.Rating.length > 1)
      document.getElementById("postRatting").innerHTML = this.Rating[1];
    else
      document.getElementById("postRatting").innerHTML = "-";
    document.getElementById("postName").innerHTML = this.Name;
    document.getElementById("postTitle").innerHTML = this.PostTitle;
    document.getElementById("postText").innerHTML = this.FullPost;
    document.getElementById("postLink").innerHTML = "<a href='"+ this.Link + "'>More on "+ this.Name +"</a> &bull; <a href='"+ this.PostLink +"#post'>Post A Comment</a> &bull; <a href='"+ this.PostLink +"'>Permalink</a>";
  }
  
  //over writes the to-string function
  Object.prototype.toString = function()
  {
    rtnRat = 10-this.Rating[0];
    
    if (rtnRat < 10)
      rtnRat = "0"+rtnRat;
    else
       rtnRat = rtnRat;

    return rtnRat +" "+ this.Name +" "+ this.ID;
  }
}



//*********************************************************************************************
//object to control the meter
//*********************************************************************************************

function meterControl()
{
  this.Dem = new Array();
  this.Rep = new Array();
  this.All = new Array();
  
  this.mostRecent = "";
  
  //adds a candidate to the correct set
  this.push = function(entry)
  {
    //finds the most recent post
    if (this.mostRecent == "" || Date.parse(entry.Date[0]) > Date.parse(this.mostRecent.Date[0]))
    {
      this.mostRecent = entry;
    }
      
    //builds the list of all entries by ID & Name
    this.All[entry.ID] = entry;
    this.All[entry.Name] = entry;
    
    //adds entries to the correct side
    if (entry.PartyCode() == "D")
      this.Dem[this.Dem.length] = entry;
    else if (entry.PartyCode() == "R")
      this.Rep[this.Rep.length] = entry;
  }
  
  //gets an element by ID
  this.getById = function(id)
  {
    return this.All[id];
  }
  
  //sorts the candidates by rating
  this.sortAll = function()
  {
    this.Dem = this.Dem.sort();
    this.Rep = this.Rep.sort();
  }
  
  //fills in the meter
  this.display = function()
  {
    this.sortAll();
    
    //displays the Demsacrats
    for (tmpC=0;tmpC<this.Dem.length&&tmpC<pplPerSide;tmpC++)
      this.Dem[tmpC].createContainer(tmpC);

    //displays the Republicans
    for (tmpC=0;tmpC<this.Rep.length&&tmpC<pplPerSide;tmpC++)
      this.Rep[tmpC].createContainer(tmpC);
      
    this.mostRecent.select();
  }
}



//*********************************************************************************************
// the popup text dialog box
//*********************************************************************************************

defaultHide = 10;
hideDelay = 0;
hidePause = 0;
curHover = "";
function textBox()
{
  this.postID = "";
  this.container = document.getElementById("hoverTxt");

  //checks fo the corect container
  if (this.container != null)
  {
    this.container.onmouseover = function() {hidePause = 1;};
    this.container.onmouseout = function() {hidePause = 0;};
  }
  
  //displays an elements box
  this.display = function(dspEle, hovEle)
  {
    if (dspEle != selectedCand)
    {
      this.postID = dspEle.ID;
      curHover =  hovEle;
      this.container.onclick = function() {faceClick(curHover);};
      //shows the dialog box
      hideDelay = defaultHide;
      this.container.style.display = "block";
      //moves the dialog to the correct location
      setPosition(this.container, dspEle.Display);

      //shows the correct background
      setBackground(this.container,imagePath +"txtPopup_"+ dspEle.PartyCode() +".png");
    
      //fills in the text for the dialog box
      this.container.innerHTML = dspEle.generatePopup()
    } else
      this.hide();
  }
  
  //hides the dialog box
  this.hide = function()
  {
    hidePause = 0;
    hideDelay = 0;
    if (this.container != null)
      this.container.style.display = "none";
  }
  
  //checks to see if the popup should be hidden and hide it if necessary
  this.hideCheck = function()
  {
    if (hideDelay < 0)
      this.hide();
    else if (hidePause)
        hideDelay = defaultHide;
      else
        hideDelay--;
  }
}



//*********************************************************************************************
// the graph object
//*********************************************************************************************

function graphArea(grObject)
{
  //sets the globals
  this.grLineWidth = 4;
  this.grWidth = 35;
  this.grHeight = 18;
  this.graphData = grObject.Rating;
  this.graphLabels = grObject.Date;

  //sets the colors used
  if (grObject.PartyCode() == "D")
  {
    this.graphMainColor = "#a1322b";
    this.graphAltColor = "#ed4e51";
  }
  else  
  {
    this.graphMainColor ="#0f5881";
    this.graphAltColor = "#3495d0";
  }
  //sets the background of the graph
  document.getElementById("graph").style.backgroundImage = "url("+ imagePath +"graph_"+ grObject.PartyCode() +".jpg)";
  //builds the drawing object
  this.graph = new jsGraphics(document.getElementById("graphArea"));
  
  //calculates the starting data point and the ending data point
  if (this.graphData.length < 9)
    this.grStrPt = this.graphData.length;
  else
    this.grStrPt = 9;

  this.grEndPt = 0;

  //sets up the x axis labels
  labelArea1 = document.getElementById("xLabel1")
  labelArea2 = document.getElementById("xLabel2")
  labelArea = labelArea1;
  //builds the label
  this.getLabel = function(lblNum)
  {
    lblDate = new Date(this.graphLabels[lblNum]);
    lblTxt = (lblDate.getMonth()+1) +"/"+ lblDate.getDate() +"/";
    tmpYr = ""+lblDate.getFullYear();
    lblTxt += tmpYr.substring(2);
    return lblTxt;
  }
  
  //writes the labels out
  for (tmpP=this.grStrPt; tmpP>this.grEndPt; tmpP--)
  {
      //creates the label for the current point
    curLbl = document.createElement("li");
    curLbl.innerHTML = this.getLabel(tmpP-1);

    //flips the label area
    if (labelArea == labelArea2)
      labelArea = labelArea1;
    else
      labelArea = labelArea2;
    //adds the label
    labelArea.appendChild(curLbl);
  }
  
  //draws the graph
  this.draw = function ()
  {
    //grabs the graph area
  //calculates the offsets
    refObj = document.getElementById("graphArea");
    ofstHeight = refObj.clientHeight;
    ofstLeft = refObj.offsetLeft;
    ofstTop = refObj.offsetTop;
    while(refObj = refObj.offsetParent)
    {
      ofstLeft += refObj.offsetLeft;
      ofstTop += refObj.offsetTop;
    }
    
    //draws the graph outline
    tmpCurpos = 0;
    this.graph.setStroke(this.grLineWidth);
    this.graph.setColor(this.graphMainColor);
    for (tmpP=this.grStrPt-1; tmpP>this.grEndPt; tmpP--)
    {

      //calculates the line start
      tmpX1 = ( tmpCurpos*this.grWidth)+ofstLeft;
      tmpY1 = (ofstHeight-(this.graphData[tmpP]*this.grHeight))+ofstTop-2;
      //calculates the line end
      tmpX2 = ( (tmpCurpos+1)*this.grWidth)+ofstLeft;
      tmpY2 = (ofstHeight-(this.graphData[tmpP-1]*this.grHeight))+ofstTop-2;
      //connects two points
      this.graph.drawLine(tmpX1, tmpY1, tmpX2, tmpY2);
      this.graph.paint();

      tmpCurpos++;
    }

    //draws the inner line
    tmpCurpos = 0;
    this.graph.setStroke(this.grLineWidth - 2);
    this.graph.setColor(this.graphAltColor);
    for (tmpP=this.grStrPt-1; tmpP>this.grEndPt; tmpP--)
    {
      //calculates the line start
      tmpX1 = ( tmpCurpos*this.grWidth)+ofstLeft;
      tmpY1 = (ofstHeight-(this.graphData[tmpP]*this.grHeight))+ofstTop-2;
      //calculates the line end
      tmpX2 = ( (tmpCurpos+1)*this.grWidth)+ofstLeft;
      tmpY2 = (ofstHeight-(this.graphData[tmpP-1]*this.grHeight) )+ofstTop-2;
     
      //connects two points
      this.graph.drawLine(tmpX1+1, tmpY1+1, tmpX2+1, tmpY2+1);
      this.graph.paint();
      
      tmpCurpos++;
    }
  }
  
  //redraws the graph
  this.redraw = function()
  {
    this.graph.clear();
    this.draw();
  }
  window.onresize = function() {recent.redraw()}
  window.onload = function() {recent.draw()}
}