<?xml version="1.0" encoding="UTF-8"?>
<Module>
    <ModulePrefs 
     title="__MSG_textbox_gadget__"
     description="Add more room to express yourself with this extra text box."
     thumbnail="http://storage.ning.com/topology/rest/1.0/file/get/3915025731?profile=original"
     directory_title="__MSG_textbox_gadget__"
     screenshot="http://os.ning.com/apps/textbox/gfx/screenshot.png"
     title_url="http://os.ning.com/apps/textbox/gadget.php"
     author="Ning"
     author_email="ninghelp@ning.com"
     author_affiliation="Ning, Inc."
     author_location="Palo Alto, CA, USA" >
        <Locale messages="http://os.ning.com/local/home/xncore/playground/597/907/os/apps/textbox/locale/ALL_ALL.xml"/> 
        <Locale lang="en" messages="http://os.ning.com/local/home/xncore/playground/597/907/os/apps/textbox/locale/ALL_ALL.xml"/> 
        <Locale lang="pt" messages="http://os.ning.com/local/home/xncore/playground/597/907/os/apps/textbox/locale/pt_BR.xml"/> 
        <Require feature="opensocial-0.7"/>
        <Require feature="dynamic-height"/>
        <Require feature="settitle"/>
        <Require feature="views" />
        <Require feature="skins" />
    </ModulePrefs>
    <Content type="html" view="default,canvas,profile,home">
        <![CDATA[
        <script>
            appUrl = 'http://os.ning.com/local/home/xncore/playground/597/907/os/apps/textbox'
        </script>
        <script>//global vars
var viewer
var owner
var env
var config = {
    html : ''
}

//Not everyone has firebug... c'mon, go get it http://getfirebug.com
if (!console) {
  var console = {}
  console.log = function(text){
    return
  }
}

/* returns the style reference for a given css rule */
function getStyle (cssrule) {
    for (var i in document.styleSheets) {
        var styleRules = (document.styleSheets[i].rules) ? document.styleSheets[i].rules :
                         (document.styleSheets[i].cssRules) ? document.styleSheets[i].cssRules : [];
        for (var j=0; j<styleRules.length; j++){
            if (styleRules[j].selectorText.toUpperCase() == cssrule.toUpperCase()) {
                return styleRules[j];
            }
        }
    }
    return null;
}

/* Applies the skin from the Open Social container */
function updateCSS() {
    var bgColor     = gadgets.skins.getProperty(gadgets.skins.Property.BG_COLOR);
    var fontColor   = gadgets.skins.getProperty(gadgets.skins.Property.FONT_COLOR);
    var anchorColor = gadgets.skins.getProperty(gadgets.skins.Property.ANCHOR_COLOR);
    var gadgetStyle = getStyle('.gadget');
    var gadgetLinks = getStyle('.gadget a');
    var gadgetButtons = getStyle('input.button');
    gadgetStyle.style.color = fontColor;
    gadgetStyle.style.backgroundColor = bgColor;
    gadgetLinks.style.color = anchorColor;
    gadgetButtons.style.backgroundColor = anchorColor;
    var buttonContrast = Contrast.test(anchorColor, '#222222');
    if (buttonContrast == true) {
      gadgetButtons.style.color = '#222222';
    } else {
      gadgetButtons.style.color = '#FFFFFF';
    }
}

/*
  Color Contrast | Andrew Waer 
  Origins: http://juicystudio.com/services/colourcontrast.php

  Usage:

  // Contrast test for two colors
  // returns passing score OR false if test fails
  Contrast.test('#ffffff', '#000000');

  // find best match from one or two color sets
  // returns array containing two hex values OR false if no match
  Contrast.match('#ffffff', ['#000000', '#336699']);
  Contrast.match(['#ffffff', '#000000', '#336699']);
  Contrast.match(['#ffffff','#ffffcc'], ['#000000', '#336699']);
*/

var Contrast = function()
{
  // private functions and properties
  var _private =
  {
    min : { 
      'brightness': 125, 
      'difference': 500 
    },
    brightness : function(rgb1, rgb2){
      var b1 = ((rgb1.r * 299) + (rgb1.g * 587) + (rgb1.b * 114)) / 1000;
      var b2 = ((rgb2.r * 299) + (rgb2.g * 587) + (rgb2.b * 114)) / 1000;
      return Math.abs(Math.round(b1-b2));
    },
    difference : function(rgb1, rgb2){
      var diff = (Math.max(rgb1.r, rgb2.r) - Math.min(rgb1.r, rgb2.r)) + 
                 (Math.max(rgb1.g, rgb2.g) - Math.min(rgb1.g, rgb2.g)) + 
                 (Math.max(rgb1.b, rgb2.b) - Math.min(rgb1.b, rgb2.b));
      return Math.abs(Math.round(diff));
    },
    rgb : function(hex){
      hex = hex.replace('#','');
      var rgb = {
        r: parseInt(hex[0] + hex[1], 16),
        g: parseInt(hex[2] + hex[3], 16),
        b: parseInt(hex[4] + hex[5], 16)
      };
      return rgb;
    }
  };
  // public functions and properties
  var _public =
  {
    test : function(hex1, hex2){
      var rgb1 = _private.rgb(hex1);
      var rgb2 = _private.rgb(hex2);
      var brightness = _private.brightness(rgb1, rgb2);
      var difference = _private.difference(rgb1, rgb2);
      return (
        brightness >= _private.min.brightness && difference >= _private.min.difference
          ? ((brightness - _private.min.brightness) + (difference - _private. min.difference))
          : false
      );
    },
    match : function(hex1, hex2){
      var total_score, i, j;

      if (typeof hex1 == 'string') {hex1 = [hex1];}
      if (typeof hex2 == 'string') {hex2 = [hex2];}
      var best_match = { 
        score: 0,
        hex1:  null,
        hex2:  null
      };
      if (hex2 == null){
        for (i=0; i<hex1.length; i++){
          for (j=0; j<hex1.length; j++){
            total_score = _public.test(hex1[i], hex1[j]);
            if (total_score > best_match.score){
              best_match.score = total_score;
              best_match.hex1 = hex1[i];
              best_match.hex2 = hex1[j];
            }
          }
        }
      } 
      else {
        for (i=0; i<hex1.length; i++){
          for (j=0; j<hex2.length; j++){
            total_score = _public.test(hex1[i], hex2[j]);
            if (total_score > best_match.score){
              best_match.score = total_score;
              best_match.hex1 = hex1[i];
              best_match.hex2 = hex2[j];
            }
          }
        }
      }
      return (
        best_match.score > 0
        ? [ best_match.hex1, best_match.hex2 ]
        : false
      );
    }
  };
  return _public;
}();

/**
 * Request information about the gadget owner and viewer
 */
function requestInfo(callback) {
  var req = opensocial.newDataRequest();
  req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.OWNER), "owner");
  req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), "viewer");
  req.send(callback);
}

function loadConfig(){
    var req = opensocial.newDataRequest();
    req.add(
        req.newFetchPersonAppDataRequest(
            opensocial.DataRequest.PersonId.OWNER,
            "htmlContent"),
        "get_data");
    req.send(configLoaded);    
    env = opensocial.getEnvironment();
}

function html_entity_decode(html) {
  var ta = document.createElement("textarea");
  ta.innerHTML = html.replace(/</g,"&lt;").replace(/>/g,"&gt;");
  return ta.value;
}

function configLoaded(response) {
    var htmlbox  = document.getElementById('html-box')
    if (response.get("get_data").hadError()) {
        htmlbox.innerHTML = 'error loading textbox'
    } else {
        var data = response.get("get_data").getData();
        if (data[owner.getId()]) {
            htmlbox.innerHTML = html_entity_decode(data[owner.getId()]["htmlContent"])
            addTargetBlank();
        } else {
            htmlbox.innerHTML = '<p>This Text Box is currently empty.</p>'
        }
        if(viewer.isOwner()){
            document.getElementById('admin-bar').style.display = 'block'
        }
        gadgets.window.adjustHeight()
    }
};


function init() {
    updateCSS();
    gadgets.window.adjustHeight();
    requestInfo(function (data) {
        viewer = data.get("viewer").getData();
        owner  = data.get("owner").getData();
        loadConfig()
        displayFooter()
    })
}

function displayFooter(){
    console.log('DisplayFooter')
    var whichfooter = (env.getDomain().indexOf('ning.com') == -1 ) ? 'others' : 'ning';
    var footer = document.getElementById(whichfooter + '-footer')
    if (footer) { footer.style.display = 'block' }
}


function toggleBoxContent(){
    console.log('editBoxContent')
    var htmlbox  = document.getElementById('html-box')
    var htmlform = document.getElementById('edit-html-form')
    var htmlinput = document.getElementById('html-content-input')
    var editlink = document.getElementById('edit-link')
    var temp = htmlform.style.display
    if(temp=='none') {
        htmlinput.value = htmlbox.innerHTML
        editlink.innerHTML = "Cancel"
    } else {
        editlink.innerHTML = "Settings"
    }
    htmlform.style.display = htmlbox.style.display
    htmlbox.style.display = temp
    gadgets.window.adjustHeight()
    return false
}

function updateBox(){
    console.log('updateBox')
    var htmlinput = document.getElementById('html-content-input').value
    scrubHtml(htmlinput)
    return false
}

function scrubHtml(html){
    var url = appUrl+'/gadget.php';
    var params = {};
    var postdata = {
        action : 'scrub',
        html : html
    };
    params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
    params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
    gadgets.io.makeRequest(url+'?t='+ new Date().getTime()+'&'+gadgets.io.encodeValues(postdata), onHtmlScrubbed, params);
}

function onHtmlScrubbed(ret){
    console.log('onHtmlScrubbed')
    console.log(ret)
    var htmlContent = ''
    if(ret.errors && ret.errors.length>0){
        alert('Error - ' + ret.errors[0])
    } else {
        if (ret.data.result != 'success') {
            alert(ret.data.result);
        } else {
            htmlContent = ret.data.html
            config.html = htmlContent
            var req = opensocial.newDataRequest();
            console.log('htmlContent')
            console.log(htmlContent)
            req.add(
                req.newUpdatePersonAppDataRequest("VIEWER", "htmlContent", htmlContent),
                "set_data");
            req.send(onBoxUpdated);
        }
    }
}

function onBoxUpdated(response)  {
    console.log('onBoxUpdated')
    var htmlbox  = document.getElementById('html-box')
  if (response.get("set_data").hadError()) {
      alert('Error updating box')
  } else {
      htmlbox.innerHTML = config.html
      toggleBoxContent()
      addTargetBlank()
  }
};

/**
* adds target="_blank" to all links in the gadget
**/
function addTargetBlank(){
    var page_links = document.links;
    for (var i=0; i<page_links.length; i++){
        page_links[i].setAttribute('target', '_blank');
    }
}
gadgets.util.registerOnLoadHandler(init);</script>
        <style>.gadget {
    /* is replaced when the skin is applied */
    background-color: #fff;
    color: #999;
    padding:1px;
    padding-bottom:10px;
}
.gadget a {
    /* is replaced when the skin is applied */
    color: #00f;
}

#html-content-input {
    width: 100%;
    height: 300px;
}

#html-content-input:focus {
    background-color:#FFFFEE;
}

#admin-bar {
    text-align: right;
    font-size:small;
}

a.edit, .edit {
    background:url(http://os.ning.com/local/home/xncore/playground/597/907/os/apps/textbox/gfx/set_actions.gif) no-repeat 0 -192px;
    padding-left:17px;
}
.primary-action{
    font-weight:bold;
}

.footer {
    clear:left;
    text-align:center;
    font-size:x-small;
}

/* Typography */
.gadget {font-size:12px !important;}
h1 {font-size:1.4em}
h2 {font-size:1.3em}
h3 {font-size:1.2em}
h4 {font-size:1.1em}
h1, h2, h3, h4, p {margin:.25em 0 .75em;}
input.text, select {margin:0 0 .75em;}

/* Spacing */
ul, ol, li {margin-left:0;padding-left:0;}
p.buttongroup {
	margin:0.5em 0;
	padding-top:.7em;
	border-top:1px solid #ccc;
	text-align:right;
	clear:both;
	overflow:visible !important;
}

a.button,
input.button {
	display:inline-block;
	width:auto;
	border:1px solid #aaa;
	font-size:1em;
	text-decoration:none;
	color:#333;
	overflow:visible;
	white-space:nowrap;
	line-height:1em!important;
  padding:.35em .6em .45em;
}
/* ff2 */
a.button, x:-moz-any-link {
  padding:.28em .53em .226em;
}
input.button, x:-moz-any-link {
	padding:.2em .3em .15em;
}
/* ff3 */
a.button, x:-moz-any-link, x:default {
  padding:.4em .532em .34em;
}
input.button, x:-moz-any-link, x:default {
	padding:.21em .3em .16em;
}
/* ie: */
a.button {
  *margin-bottom:-.3em;
	*padding:.3em .57em;
}
input.button {
	*padding:.2em .5em .1em;
}</style>
        ]]>
    </Content>
    <Content type="html" view="default,canvas,profile,home"><![CDATA[<div class="gadget">    <div id="admin-bar" style="display:none;"><a class="edit" href="#" onclick="return toggleBoxContent()" id="edit-link">Settings</a></div>
    <form id="edit-html-form" style="display:none;" onsubmit="return updateBox()">
        <textarea name="html-content" id="html-content-input"></textarea>
        <p class="buttongroup">
            <input type="submit" class="primary-action button" value="Save"/>
            <input type="button" onclick="toggleBoxContent();" class="button" value="Cancel"/>
        </p>
    </form>
    <div id="html-box" style="display:block;"></div>
</div>]]></Content><Content type="html" view="canvas"><![CDATA[<div class="gadget"><p id="ning-footer" class="footer" style="display:none;"></p>

<p id="others-footer" class="footer" style="display:none;"> 
    __MSG_brought_to_you_by__ <a href="http://www.ning.com" target="_blank">__MSG_ning__</a>
    | <a href="http://about.ning.com/applicationstos.php" target="_blank">__MSG_terms_of_use__</a>
</p>
</div>]]></Content></Module>