// Copyright 2006 Junction Networks Inc.
// All Rights Reserved
//
// A simple script which utilizes the Junction Networks API to setup a call (CallSetup).
//
// Author: John Riordan <john@junctionnetworks.com>
//

//
// The following required variables can be modified after this script has been loaded.
// If the page elements with the same id exist, their values will be used.
//
// Required: the SIP addresses to place the call from/to (caller/callee)
var jn_FromAddress = '';  // SIP address the call is placed from
var jn_ToAddress = '';    // SIP address the call is placed to

// Optional: if jn_ToAddress is not provided, an attempt will be made to create it from these.
var jn_ToDomain = '';     // SIP address domain the call is placed to
var jn_ToUser = '';       // SIP address user the call is placed to

// the URL of the Junction Networks API
var jn_apiUrl = "http://www.jnctn.com/restapi";

//
// Click-to-Call AJAX Example
//

function $(id) { return document.getElementById(id); }

function cleanup() {
  jn_FromAddress = '';
  jn_ToAddress = '';
  jn_ToDomain = '';
  jn_ToUser = '';
}

function doCallSetup() {
  // if not set already, attempt to set jn_FromAddress
  if(jn_FromAddress == '') {
    if($('jn_FromAddress')) {
      jn_FromAddress = $('jn_FromAddress').value;
    }
    else {
      alert("Click-to-Call: Please enter a FromAddress");
      cleanup();
      return false;
    }
  }

  // if not set already, attempt to set jn_ToAddress
  if(jn_ToAddress == '') {
    if($('jn_ToAddress')) {
      jn_ToAddress = $('jn_ToAddress').value;
    }
    else {
      if(jn_ToDomain == '') {
        if($('jn_ToDomain')) {
          jn_ToDomain = $('jn_ToDomain').value;
        }
        else if(jn_FromAddress.indexOf('@') != -1) {
          jn_ToDomain = jn_FromAddress.substr(jn_FromAddress.indexOf('@') + 1);
        }
        else {
          alert("Click-to-Call: Please enter a FromAddress");
          cleanup();
          return false;
        }
      }
      if(jn_ToUser == '') {
        if($('jn_ToUser')) {
          jn_ToUser = $('jn_ToUser').value;
        }
        else if($('jn_PhoneNumberAreaCode') &&
                $('jn_PhoneNumberFirstThree') &&
                $('jn_PhoneNumberLastFour')) {
          jn_ToUser = 
            "1" +
            $('jn_PhoneNumberAreaCode').value +
            $('jn_PhoneNumberFirstThree').value +
            $('jn_PhoneNumberLastFour').value;
        }
        else {
          alert("Click-to-Call: Please enter a phone number");
          cleanup();
          return false;
        }
      }
      jn_ToAddress = jn_ToUser+"@"+jn_ToDomain;
    }
  }

  // call the REST API (place the call)
  var query = 
    "Action=CallSetup&Output=json&Callback=callbackFunc" +
    "&FromAddress=" + jn_FromAddress +
    "&ToAddress=" + jn_ToAddress;

  request = jn_apiUrl + '?' + query;
  aObj = new JSONscriptRequest(request);
  aObj.buildScriptTag();
  aObj.addScriptTag();

  // if they exist, update the info messages
  if($("jn_RequestMessage")) {
    $("jn_RequestMessage").innerHTML = "";
    $("jn_RequestMessage").innerHTML = "Setting up call...";
    Fat.fade_element($("jn_RequestMessage"));
  }
  if($("jn_ResponseMessage")) {
    $("jn_ResponseMessage").innerHTML = "";
    $("jn_ResponseMessage").innerHTML = "&#160;";
  }

  cleanup();
  return true;
}

function callbackFunc(jsonData) {

  // check for a valid response
  if(!jsonData.Response) {
    alert("Error: Invalid Response - " + jsonData.toString());
  }
  else {
    var isValid = jsonData.Response.Context.Request.IsValid;
    var isCompleted = jsonData.Response.Context.Action.IsCompleted;

    // check for errors
    if(isCompleted == "false") {
      var errorMessage = "Error: ";
      if(jsonData.Response.Context.Request.Errors) {
        if(jsonData.Response.Context.Request.Errors.Error.length) {
          for(var error in jsonData.Response.Context.Request.Errors.Error) {
            errorMessage += error.parameter + ": " + error.message + "\n";
          }
        }
        else {
          var error = jsonData.Response.Context.Request.Errors.Error;
          errorMessage += error.Parameter + ': ' + error.Message;
        }
      }
      if($("jn_ResponseMessage")) {
        $("jn_ResponseMessage").innerHTML = "";
        $("jn_ResponseMessage").innerHTML = errorMessage;
        Fat.fade_element($("jn_ResponseMessage"));
      }
    }
    // otherwise things look like they worked
    else {
      var code = jsonData.Response.Result.CallSetup.FinalResponse.Code;
      var message = jsonData.Response.Result.CallSetup.FinalResponse.Message;
      if($("jn_ResponseMessage")) {
        $("jn_ResponseMessage").innerHTML = "";
        if(code == "200")
          $("jn_ResponseMessage").innerHTML = "Call placed.";
        else
          $("jn_ResponseMessage").innerHTML = "Call not made - "  + message;
        Fat.fade_element($("jn_ResponseMessage"));
      }
    }
  }

  // remove the script tag
  aObj.removeScriptTag();

  return;
}


//
// JSONscriptRequest 
//

// Constructor -- pass a REST request URL to the constructor
function JSONscriptRequest(fullUrl) {
    // REST request path
    this.fullUrl = fullUrl; 
    // Keep IE from caching requests
    this.noCacheIE = '&noCacheIE=' + (new Date()).getTime();
    // Get the DOM location to put the script tag
    this.headLoc = document.getElementsByTagName("head").item(0);
    // Generate a unique script tag id
    this.scriptId = 'JscriptId' + JSONscriptRequest.scriptCounter++;
}

// Static script ID counter
JSONscriptRequest.scriptCounter = 1;

// buildScriptTag method
//
JSONscriptRequest.prototype.buildScriptTag = function () {

    // Create the script tag
    this.scriptObj = document.createElement("script");
    
    // Add script object attributes
    this.scriptObj.setAttribute("type", "text/javascript");
    this.scriptObj.setAttribute("charset", "utf-8");
    this.scriptObj.setAttribute("src", this.fullUrl + this.noCacheIE);
    this.scriptObj.setAttribute("id", this.scriptId);
}
 
// removeScriptTag method
// 
JSONscriptRequest.prototype.removeScriptTag = function () {
    // Destroy the script tag
    this.headLoc.removeChild(this.scriptObj);  
}

// addScriptTag method
//
JSONscriptRequest.prototype.addScriptTag = function () {
    // Create the script tag
    this.headLoc.appendChild(this.scriptObj);
}


//
// The Fade Anything Technique
//

var Fat = {
  make_hex : function (r,g,b) 
  {
    r = r.toString(16); if (r.length == 1) r = '0' + r;
    g = g.toString(16); if (g.length == 1) g = '0' + g;
    b = b.toString(16); if (b.length == 1) b = '0' + b;
    return "#" + r + g + b;
  },

  fade_element : function (element, fps, duration, from, to) 
  {
    if (!fps) fps = 30;
    if (!duration) duration = 1000;
    if (!from || from=="#") from = "#FF0000";
    if (!to) to = this.get_bgcolor(element);

    var frames = Math.round(fps * (duration / 1000));
    var interval = duration / frames;
    var delay = interval;
    var frame = 0;
    
    if (from.length < 7) from += from.substr(1,3);
    if (to.length < 7) to += to.substr(1,3);
    
    var rf = parseInt(from.substr(1,2),16);
    var gf = parseInt(from.substr(3,2),16);
    var bf = parseInt(from.substr(5,2),16);
    var rt = parseInt(to.substr(1,2),16);
    var gt = parseInt(to.substr(3,2),16);
    var bt = parseInt(to.substr(5,2),16);
    
    var r,g,b,h;
    while (frame < frames)
    {
      r = Math.floor(rf * ((frames-frame)/frames) + rt * (frame/frames));
      g = Math.floor(gf * ((frames-frame)/frames) + gt * (frame/frames));
      b = Math.floor(bf * ((frames-frame)/frames) + bt * (frame/frames));
      h = this.make_hex(r,g,b);
      
      setTimeout(this.makeTimer(element, h), delay);

      frame++;
      delay = interval * frame; 
    }
    setTimeout(this.makeTimer(element, to), delay);
  },
  
  makeTimer : function(element, color) {
    return function() { Fat.set_bgcolor(element, color); }
  },
  
  set_bgcolor : function (element, c)
  {
    element.style.backgroundColor = c;
  },
  
  get_bgcolor : function (element)
  {
    while(element)
    {
      var c;
      if (window.getComputedStyle) c = window.getComputedStyle(element,null).getPropertyValue("background-color");
      if (element.currentStyle) { c = element.currentStyle.backgroundColor; }
      if ((c != "" && c != "transparent") || element.tagName == "BODY") { break; }
      element = element.parentNode;
    }
    if (c == undefined || c == "" || c == "transparent") c = "#FFFFFF";
    var rgb = c.match(/rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/);
    if (rgb) c = this.make_hex(parseInt(rgb[1]),parseInt(rgb[2]),parseInt(rgb[3]));
    return c;
  }
}


