text: angular.module('MRT', ['app-parameters', 'ui.bootstrap', 'ui.router', 'ngCookies', 'ngTable', 'ui.select', 'ngSanitize', 'angular-loading-bar', 'LocalStorageModule', 'angular-cache', 'ngHandsontable', 'ngNotify']);
  // 'ui.slider',
  angular.module('MRT').config(function (localStorageServiceProvider) {
    localStorageServiceProvider
      .setPrefix('mrt');
  });
  
  angular.module('MRT').config(function (CacheFactoryProvider) {
      angular.extend(CacheFactoryProvider.defaults, { maxAge: 15 * 60 * 1000 });
  });
  
  // Production steps of ECMA-262, Edition 5, 15.4.4.14
  // Reference: http://es5.github.io/#x15.4.4.14
  if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(searchElement, fromIndex) {
  
      var k;
  
      // 1. Let O be the result of calling ToObject passing
      //    the this value as the argument.
      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }
  
      var O = Object(this);
  
      // 2. Let lenValue be the result of calling the Get
      //    internal method of O with the argument "length".
      // 3. Let len be ToUint32(lenValue).
      var len = O.length >>> 0;
  
      // 4. If len is 0, return -1.
      if (len === 0) {
        return -1;
      }
  
      // 5. If argument fromIndex was passed let n be
      //    ToInteger(fromIndex); else let n be 0.
      var n = +fromIndex || 0;
  
      if (Math.abs(n) === Infinity) {
        n = 0;
      }
  
      // 6. If n >= len, return -1.
      if (n >= len) {
        return -1;
      }
  
      // 7. If n >= 0, then Let k be n.
      // 8. Else, n<0, Let k be len - abs(n).
      //    If k is less than 0, then let k be 0.
      k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
  
      // 9. Repeat, while k < len
      while (k < len) {
        // a. Let Pk be ToString(k).
        //   This is implicit for LHS operands of the in operator
        // b. Let kPresent be the result of calling the
        //    HasProperty internal method of O with argument Pk.
        //   This step can be combined with c
        // c. If kPresent is true, then
        //    i.  Let elementK be the result of calling the Get
        //        internal method of O with the argument ToString(k).
        //   ii.  Let same be the result of applying the
        //        Strict Equality Comparison Algorithm to
        //        searchElement and elementK.
        //  iii.  If same is true, return k.
        if (k in O && O[k] === searchElement) {
          return k;
        }
        k++;
      }
      return -1;
    };
  }
  
  angular.module('app-parameters',[])  
    .constant('env', {"apiUrl":"http://192.168.33.99/web/app_dev.php/api"});
  'use strict';
  
  /**
   * Route configuration for the Dashboard module.
   */
  angular.module('MRT').config(['$stateProvider', '$urlRouterProvider',
      function ($stateProvider, $urlRouterProvider) {
  
          // For unmatched routes
          $urlRouterProvider.otherwise('/');
  
          // Application routes
  
          $stateProvider
              .state('index', {
                  url: '/',
                  controller: 'AuthenticationCtrl',
                  templateUrl: 'module/mrt/app/templates/index.html'
              })
              .state('dashboard', {
                  url: '/dashboard',
                  controller: 'DashboardCtrl',
                  templateUrl: 'module/mrt/app/templates/dashboard.html'
              })
              .state('geomodel-weight', {
                  url: '/geomodel/weight/:id',
                  controller: 'GeoModelWeightCtrl',
                  templateUrl: 'module/mrt/geomodel/templates/weight-index.html'
              }).state('geomodel', {
                  url: '/geomodel',
                  controller: 'GeoModelCtrl',
                  templateUrl: 'module/mrt/geomodel/templates/index.html'
              }).state('geomodel-create-country-selection', {
                  url: '/geomodel/create/country-selection',
                  controller: 'GeoModelCreateCountrySelection',
                  templateUrl: 'module/mrt/geomodel/templates/create/country-selection.html'
              })
              .state('geomodel-create-indicator-selection', {
                  url: '/geomodel/create/indicator-selection',
                  controller: 'GeoModelCreateIndicatorSelection',
                  templateUrl: 'module/mrt/geomodel/templates/create/indicator-selection.html'
              })
              .state('geomodel-vs-model', {
                  url: '/geomodel/create/vs-model/:id',
                  controller: 'GeoModelVsModel',
                  templateUrl: 'module/mrt/geomodel/templates/create/vs-model.html'
              })
              .state('geomodel-create-model', {
                  url: '/geomodel/create/model/:id/:type',
                  controller: 'GeoModelCreateModel',
                  templateUrl: 'module/mrt/geomodel/templates/create/model.html'
              })
              .state('geomodel-gallery', {
                  url: '/geomodel/gallery',
                  controller: 'GeoModelCreateModel',
                  templateUrl: 'module/mrt/geomodel/templates/create/model-gallery.html'
              })
              .state('geography', {
                  url: '/geography',
                  controller: 'GeographyCtrl',
                  templateUrl: 'module/mrt/geography/templates/index.html'
              })
              .state('geogroup', {
                  url: '/geogroup',
                  controller: 'GeoGroupCtrl',
                  templateUrl: 'module/mrt/geogroup/templates/index.html'
              })
              .state('geogroup-view', {
                  url: '/geogroup-view/:id',
                  controller: 'GeoGroupViewCtrl',
                  templateUrl: 'module/mrt/geogroup/templates/view.html'
              })
              .state('geoindicatorgroup', {
                  url: '/geoindicatorgroup',
                  controller: 'GeoIndicatorGroupCtrl',
                  templateUrl: 'module/mrt/geoindicatorgroup/templates/index.html'
              })
              .state('geoindicatorgroup-view', {
                  url: '/geoindicatorgroup-view/:id',
                  controller: 'GeoIndicatorGroupViewCtrl',
                  templateUrl: 'module/mrt/geoindicatorgroup/templates/view.html'
              })
              .state('geoindicator', {
                  url: '/geoindicator',
                  controller: 'GeoIndicatorCtrl',
                  templateUrl: 'module/mrt/geoindicator/templates/index.html',
  
              })
              .state('geoindicator-view', {
                  url: '/geoindicator/view/:id',
                  controller: 'GeoIndicatorViewCtrl',
                  templateUrl: 'module/mrt/geoindicator/templates/view.html'
              })
              .state('geoindicator-add', {
                  url: '/geoindicator/add',
                  controller: 'GeoIndicatorAddCtrl',
                  templateUrl: 'module/mrt/geoindicator/templates/add.html'
              })
              .state('geoindicator-edit', {
                  url: '/geoindicator/edit/:id',
                  controller: 'GeoIndicatorAddCtrl',
                  templateUrl: 'module/mrt/geoindicator/templates/add.html'
              })
              .state('geomodel-cluster', {
                  url: '/geomodel/cluster',
                  controller: 'GeoModelCtrl',
                  templateUrl: 'module/mrt/geomodel/templates/geomodel-cluster-index.html'
              })
              .state('geomodel-add-advance', {
                  url: '/geomodel/add-advance',
                  controller: 'GeoModelAddAdvanceCtrl',
                  templateUrl: 'module/mrt/geomodel/templates/add-advance.html'
              })
              .state('view-fund', {
                  url: '/view-fund/:phoneId',
                  controller: 'ViewFundCtrl',
                  templateUrl: 'tpls/mrt/tpls/tpls/view-fund.html'
              })
              .state('tables', {
                  url: '/tables',
                  templateUrl: 'tables.html'
              });
      }]);
  
  
  
  
  
  /**
   * Master Controller
   */
   angular.module('MRT')
   .controller('MasterCtrl', ['$scope', '$cookieStore', MasterCtrl]);
  
   function MasterCtrl($scope, $cookieStore) {
  	/**
  	 * Sidebar Toggle & Cookie Control
  	 *
  	 */
  
  	// $scope.term = 'Hairdressers';
  
  
  	var mobileView = 992;
  	$scope.app = {};
  	$scope.app.loggedIn = true;
  	$scope.app.unsavedChanges = false;
  
  
  	$scope.menu = [
  		{'ui_sref': 'geomodel', 'display': 'Models', 'class': 'menu-icon fa fa-adjust'},
  		{
  			'display': 'Data Maintenance', 
  			'class': 'menu-icon fa fa-database', 
  			'menu': [
  				{'ui_sref': 'geoindicator', 'display': 'Indicators', 'class': 'menu-icon fa fa-adjust'},
  				{'ui_sref': 'geoindicatorgroup', 'display': 'Indicator Groups', 'class': 'menu-icon fa fa-adjust'},
  				{'ui_sref': 'geography', 'display': 'Countries', 'class': 'menu-icon fa fa-adjust'},
  				{'ui_sref': 'geogroup', 'display': 'Counrty Groups', 'class': 'menu-icon fa fa-adjust'}
  			]
  		},
  		{
  			'display': 'Admin', 
  			'class': 'menu-icon fa fa-adjust', 
  			'menu': [
  				{'ui_sref': '', 'display': 'Users', 'class': 'menu-icon fa fa-adjust'},
  				{'ui_sref': '', 'display': 'User Groups', 'class': 'menu-icon fa fa-adjust'}
  			]
  		}
  	];
  
  	$scope.expandMenu = function(item) {
  		item.expand = (typeof item.expand !== 'undefined' && item.expand === true) ? false : true;
  	}
  
  
  	$scope.$on('$locationChangeStart', function(event) {
  		if ($scope.app.unsavedChanges === true) {
  			var answer = confirm("You have unsaved changes. Are you sure you want to leave this page?")
  			if (!answer) {
  				event.preventDefault();
  			}
  		}
  	});
  
  	$scope.getWidth = function() {
  		return window.innerWidth;
  	};
  
  
  
  	$scope.chartData = {
  		title: {
  			text: 'World Population (2015)',
  			subtext: 'from United Nations, Total population, both sexes combined, as of 1 July (thousands)'
  		},
  		dataRange: {
  			min: 0,
  			max: 1000000,
  			text: ['High', 'Low'],
  			realtime: false,
  			calculable: true,
  			color: ['#ffce54', '#00bff3', '#EB5367']
  		},
  		series: [
  		{
  			name: 'World Population (2010)',
  			type: 'map',
  			mapType: 'world',
  			roam: true,
  			mapLocation: {
  				y: 60
  			},
  			itemStyle: {
  				emphasis: {label: {show: true}}
  			},
  			markPoint : {
                  symbol:'emptyCircle',
                  symbolSize : function (v){
                      return 10 + v/100
                  },
                  effect : {
                      show: true,
                      shadowBlur : 0
                  },
                  itemStyle:{
                      normal:{
                          label:{show:true}
                      }
                  },
                  data : [
                    // {name: 'Afghanistan', value: 100},
  				   {name: 'Angola', value: 20},
  				   //{name: 'Albania', value: 50}
  
                  ]
              },
    			 geoCoord: {
              	'Angola': [-16.56666666, 13.46666666]
              },
  			data: [
  			{name: 'Afghanistan', value: 28397.812},
  			{name: 'Angola', value: 19549.124},
  			{name: 'Albania', value: 3150.143}
  			]
  		 },
  		 {
              name: 'Top5',
              type: 'map',
              mapType: 'world',
              roam: true,
              data:[],
              markPoint : {
                  symbol:'emptyCircle',
                  symbolSize : function (v){
                      return 10 + v/100
                  },
                  effect : {
                      show: true,
                      shadowBlur : 0
                  },
                  itemStyle:{
                      normal:{
                          label:{show:true}
                      }
                  },
                  data : [
                     // {name: 'Albania', value: 193},
                      //{name: 'Angola', value: 50},
  
                  ]
              }
          }
  		]
  	};
  
  	$scope.$watch($scope.getWidth, function(newValue, oldValue)
  	{
  		if (newValue >= mobileView)
  		{
  			if (angular.isDefined($cookieStore.get('toggle')))
  			{
  				if ($cookieStore.get('toggle') == false)
  				{
  					$scope.toggle = false;
  				}
  				else
  				{
  					$scope.toggle = true;
  				}
  			}
  			else
  			{
  				$scope.toggle = true;
  			}
  		}
  		else
  		{
  			$scope.toggle = false;
  		}
  
  	});
  
  	$scope.toggleSidebar = function()
  	{
  		$scope.toggle = !$scope.toggle;
  
  		$cookieStore.put('toggle', $scope.toggle);
  	};
  
  	window.onresize = function() {
  		$scope.$apply();
  	};
  }
  
  
  
  angular.module('MRT').controller('AuthenticationCtrl', ['$scope', '$location', 'geoModelService', 'geoGroupService', function($scope, $location, geoModelService, geoGroupService) {
  		$scope.app.loggedIn = false;
  		
  		
  		$scope.submit = function() {
  			
  			$location.path("/dashboard");
  			console.log('submit');
  			
  		};
  }]);
  angular.module('MRT').directive('loginSection', searchSection);
  function searchSection() {
      var directive = {
          restrict: 'AE',
          replace: true,
          templateUrl: 'module/mrt/authentication/templates/login.html'
      };
      return directive;
  }
  ;
  /**
   * 
   * 
   */
  angular.module('MRT').directive('baiduExample', baiduExample);
  
  function baiduExample($parse) {
  	var directive = {
  		restrict: 'AE',
  		// templateUrl: 'pension/tpls/term/term-search-pageview.html',
  		replace: true,
  		//our data source would be an array
  		//passed thru chart-data attribute
  		// scope: {data: '=chartData'},
  		link: function(scope, element, attrs) {
  // // instantiate the chart------------------
  // script plain import
  			var myChart = echarts.init(element[0]);
  
  // loading---------------------
  			myChart.showLoading({
  				text: "We're building the buildings as fast as we can...please wait! ", //loading text
  			});
  
  // ajax getting data...............
  
  // ajax callback
  			myChart.hideLoading();
  
  // use the chart-------------------
  			var option = {
  				legend: {// legend configuration
  					padding: 5, // The inner padding of the legend, in px, defaults to 5. Can be set as array - [top, right, bottom, left].
  					itemGap: 10, // The pixel gap between each item in the legend. It is horizontal in a legend with horizontal layout, and vertical in a legend with vertical layout. 
  					data: ['usd', 'gbp']
  				},
  				tooltip: {// tooltip configuration
  					trigger: 'item', // trigger type. Defaults to data trigger. Can also be: 'axis'
  				},
  				xAxis: [// The horizontal axis in Cartesian coordinates
  					{
  						type: 'category', // Axis type. xAxis is category axis by default. As for value axis, please refer to the 'yAxis' chapter.
  						data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
  					}
  				],
  				yAxis: [// The vertical axis in Cartesian coordinates
  					{
  						type: 'value', // Axis type. yAxis is value axis by default. As for category axis, please refer to the 'xAxis' chapter.
  						boundaryGap: [0.1, 0.1], // Blank border on each side of the coordinate axis. Value in the array represents percentage. 
  						splitNumber: 4                      // Applicable to value axis. The number of segments. Defaults to 5. 
  					}
  				],
  				series: [
  					{
  						name: 'usd', // series name
  						type: 'line', // chart type, line, scatter, bar, pie, radar
  						data: [112, 23, 45, 56, 233, 343, 454, 89, 343, 123, 45, 123]
  					},
  					{
  						name: 'gbp', // series name
  						type: 'line', // chart type, line, scatter, bar, pie, radar
  						data: [45, 123, 145, 526, 233, 343, 44, 829, 33, 123, 45, 13]
  					}
  				]
  			};
  			myChart.setOption(option);
  
  
  // Add some data------------------
  			option.legend.data.push('win');
  			option.series.push({
  				name: 'win', // series name
  				type: 'line', // chart type, line, scatter, bar, pie, radar
  				data: [112, 23, 45, 56, 233, 343, 454, 89, 343, 123, 45, 123]
  			});
  
  			myChart.setOption(option);
  		}
  	};
  	return directive;
  }
  /**
   * 
   * 
   */
  angular.module('MRT').directive('baiduMap', baiduMap);
  
  function baiduMap($parse) {
  	var directive = {
  		restrict: 'AE',
  		// templateUrl: 'pension/tpls/term/term-search-pageview.html',
  		replace: true,
  		//our data source would be an array
  		//passed thru chart-data attribute
  		// scope: {data: '=chartData'},
  		link: function(scope, element, attrs) {
  // // instantiate the chart------------------
  // script plain import
  			var myChart = echarts.init(element[0]);
  
  // loading---------------------
  			myChart.showLoading({
  				text: "We're building the buildings as fast as we can...please wait! ", //loading text
  			});
  
  // ajax getting data...............
  
  // ajax callback
  			myChart.hideLoading();
  
  // use the chart-------------------
  			option = {
  				title: {
  					text: 'World Population (2010)',
  					subtext: 'from United Nations, Total population, both sexes combined, as of 1 July (thousands)',
  					sublink: 'http://esa.un.org/wpp/Excel-Data/population.htm',
  					x: 'center',
  					y: 'top'
  				},
  				tooltip: {
  					trigger: 'item',
  					formatter: function(params) {
  						var value = (params.value + '').split('.');
  						value = value[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g, '$1,')
  								+ '.' + value[1];
  						return params.seriesName + '<br/>' + params.name + ' : ' + value;
  					}
  				},
  				toolbox: {
  					show: true,
  					orient: 'vertical',
  					x: 'right',
  					y: 'center',
  					feature: {
  						mark: {show: true},
  						dataView: {show: true, readOnly: false},
  						restore: {show: true},
  						saveAsImage: {show: true}
  					}
  				},
  				dataRange: {
  					min: 0,
  					max: 1000000,
  					text: ['High', 'Low'],
  					realtime: false,
  					calculable: true,
  					color: ['orangered', 'yellow', 'lightskyblue']
  				},
  				series: [
  					{
  						name: 'World Population (2010)',
  						type: 'map',
  						mapType: 'world',
  						roam: true,
  						mapLocation: {
  							y: 60
  						},
  						itemStyle: {
  							emphasis: {label: {show: true}}
  						},
  						data: [
  							{name: 'Afghanistan', value: 28397.812},
  							{name: 'Angola', value: 19549.124},
  							{name: 'Albania', value: 3150.143},
  							{name: 'United Arab Emirates', value: 8441.537},
  							{name: 'Argentina', value: 40374.224},
  							{name: 'Armenia', value: 2963.496},
  							{name: 'French Southern and Antarctic Lands', value: 268.065},
  							{name: 'Australia', value: 22404.488},
  							{name: 'Austria', value: 8401.924},
  							{name: 'Azerbaijan', value: 9094.718},
  							{name: 'Burundi', value: 9232.753},
  							{name: 'Belgium', value: 10941.288},
  							{name: 'Benin', value: 9509.798},
  							{name: 'Burkina Faso', value: 15540.284},
  							{name: 'Bangladesh', value: 151125.475},
  							{name: 'Bulgaria', value: 7389.175},
  							{name: 'The Bahamas', value: 66402.316},
  							{name: 'Bosnia and Herzegovina', value: 3845.929},
  							{name: 'Belarus', value: 9491.07},
  							{name: 'Belize', value: 308.595},
  							{name: 'Bermuda', value: 64.951},
  							{name: 'Bolivia', value: 716.939},
  							{name: 'Brazil', value: 195210.154},
  							{name: 'Brunei', value: 27.223},
  							{name: 'Bhutan', value: 716.939},
  							{name: 'Botswana', value: 1969.341},
  							{name: 'Central African Republic', value: 4349.921},
  							{name: 'Canada', value: 34126.24},
  							{name: 'Switzerland', value: 7830.534},
  							{name: 'Chile', value: 17150.76},
  							{name: 'China', value: 1359821.465},
  							{name: 'Ivory Coast', value: 60508.978},
  							{name: 'Cameroon', value: 20624.343},
  							{name: 'Democratic Republic of the Congo', value: 62191.161},
  							{name: 'Republic of the Congo', value: 3573.024},
  							{name: 'Colombia', value: 46444.798},
  							{name: 'Costa Rica', value: 4669.685},
  							{name: 'Cuba', value: 11281.768},
  							{name: 'Northern Cyprus', value: 1.468},
  							{name: 'Cyprus', value: 1103.685},
  							{name: 'Czech Republic', value: 10553.701},
  							{name: 'Germany', value: 83017.404},
  							{name: 'Djibouti', value: 834.036},
  							{name: 'Denmark', value: 5550.959},
  							{name: 'Dominican Republic', value: 10016.797},
  							{name: 'Algeria', value: 37062.82},
  							{name: 'Ecuador', value: 15001.072},
  							{name: 'Egypt', value: 78075.705},
  							{name: 'Eritrea', value: 5741.159},
  							{name: 'Spain', value: 46182.038},
  							{name: 'Estonia', value: 1298.533},
  							{name: 'Ethiopia', value: 87095.281},
  							{name: 'Finland', value: 5367.693},
  							{name: 'Fiji', value: 860.559},
  							{name: 'Falkland Islands', value: 49.581},
  							{name: 'France', value: 63230.866},
  							{name: 'Gabon', value: 1556.222},
  							{name: 'United Kingdom', value: 62066.35},
  							{name: 'Georgia', value: 4388.674},
  							{name: 'Ghana', value: 24262.901},
  							{name: 'Guinea', value: 10876.033},
  							{name: 'Gambia', value: 1680.64},
  							{name: 'Guinea Bissau', value: 10876.033},
  							{name: 'Equatorial Guinea', value: 696.167},
  							{name: 'Greece', value: 11109.999},
  							{name: 'Greenland', value: 56.546},
  							{name: 'Guatemala', value: 14341.576},
  							{name: 'French Guiana', value: 231.169},
  							{name: 'Guyana', value: 786.126},
  							{name: 'Honduras', value: 7621.204},
  							{name: 'Croatia', value: 4338.027},
  							{name: 'Haiti', value: 9896.4},
  							{name: 'Hungary', value: 10014.633},
  							{name: 'Indonesia', value: 240676.485},
  							{name: 'India', value: 1205624.648},
  							{name: 'Ireland', value: 4467.561},
  							{name: 'Iran', value: 240676.485},
  							{name: 'Iraq', value: 30962.38},
  							{name: 'Iceland', value: 318.042},
  							{name: 'Israel', value: 7420.368},
  							{name: 'Italy', value: 60508.978},
  							{name: 'Jamaica', value: 2741.485},
  							{name: 'Jordan', value: 6454.554},
  							{name: 'Japan', value: 127352.833},
  							{name: 'Kazakhstan', value: 15921.127},
  							{name: 'Kenya', value: 40909.194},
  							{name: 'Kyrgyzstan', value: 5334.223},
  							{name: 'Cambodia', value: 14364.931},
  							{name: 'South Korea', value: 51452.352},
  							{name: 'Kosovo', value: 97.743},
  							{name: 'Kuwait', value: 2991.58},
  							{name: 'Laos', value: 6395.713},
  							{name: 'Lebanon', value: 4341.092},
  							{name: 'Liberia', value: 3957.99},
  							{name: 'Libya', value: 6040.612},
  							{name: 'Sri Lanka', value: 20758.779},
  							{name: 'Lesotho', value: 2008.921},
  							{name: 'Lithuania', value: 3068.457},
  							{name: 'Luxembourg', value: 507.885},
  							{name: 'Latvia', value: 2090.519},
  							{name: 'Morocco', value: 31642.36},
  							{name: 'Moldova', value: 103.619},
  							{name: 'Madagascar', value: 21079.532},
  							{name: 'Mexico', value: 117886.404},
  							{name: 'Macedonia', value: 507.885},
  							{name: 'Mali', value: 13985.961},
  							{name: 'Myanmar', value: 51931.231},
  							{name: 'Montenegro', value: 620.078},
  							{name: 'Mongolia', value: 2712.738},
  							{name: 'Mozambique', value: 23967.265},
  							{name: 'Mauritania', value: 3609.42},
  							{name: 'Malawi', value: 15013.694},
  							{name: 'Malaysia', value: 28275.835},
  							{name: 'Namibia', value: 2178.967},
  							{name: 'New Caledonia', value: 246.379},
  							{name: 'Niger', value: 15893.746},
  							{name: 'Nigeria', value: 159707.78},
  							{name: 'Nicaragua', value: 5822.209},
  							{name: 'Netherlands', value: 16615.243},
  							{name: 'Norway', value: 4891.251},
  							{name: 'Nepal', value: 26846.016},
  							{name: 'New Zealand', value: 4368.136},
  							{name: 'Oman', value: 2802.768},
  							{name: 'Pakistan', value: 173149.306},
  							{name: 'Panama', value: 3678.128},
  							{name: 'Peru', value: 29262.83},
  							{name: 'Philippines', value: 93444.322},
  							{name: 'Papua New Guinea', value: 6858.945},
  							{name: 'Poland', value: 38198.754},
  							{name: 'Puerto Rico', value: 3709.671},
  							{name: 'North Korea', value: 1.468},
  							{name: 'Portugal', value: 10589.792},
  							{name: 'Paraguay', value: 6459.721},
  							{name: 'Qatar', value: 1749.713},
  							{name: 'Romania', value: 21861.476},
  							{name: 'Russia', value: 21861.476},
  							{name: 'Rwanda', value: 10836.732},
  							{name: 'Western Sahara', value: 514.648},
  							{name: 'Saudi Arabia', value: 27258.387},
  							{name: 'Sudan', value: 35652.002},
  							{name: 'South Sudan', value: 9940.929},
  							{name: 'Senegal', value: 12950.564},
  							{name: 'Solomon Islands', value: 526.447},
  							{name: 'Sierra Leone', value: 5751.976},
  							{name: 'El Salvador', value: 6218.195},
  							{name: 'Somaliland', value: 9636.173},
  							{name: 'Somalia', value: 9636.173},
  							{name: 'Republic of Serbia', value: 3573.024},
  							{name: 'Suriname', value: 524.96},
  							{name: 'Slovakia', value: 5433.437},
  							{name: 'Slovenia', value: 2054.232},
  							{name: 'Sweden', value: 9382.297},
  							{name: 'Swaziland', value: 1193.148},
  							{name: 'Syria', value: 7830.534},
  							{name: 'Chad', value: 11720.781},
  							{name: 'Togo', value: 6306.014},
  							{name: 'Thailand', value: 66402.316},
  							{name: 'Tajikistan', value: 7627.326},
  							{name: 'Turkmenistan', value: 5041.995},
  							{name: 'East Timor', value: 10016.797},
  							{name: 'Trinidad and Tobago', value: 1328.095},
  							{name: 'Tunisia', value: 10631.83},
  							{name: 'Turkey', value: 72137.546},
  							{name: 'United Republic of Tanzania', value: 44973.33},
  							{name: 'Uganda', value: 33987.213},
  							{name: 'Ukraine', value: 46050.22},
  							{name: 'Uruguay', value: 3371.982},
  							{name: 'United States of America', value: 312247.116},
  							{name: 'Uzbekistan', value: 27769.27},
  							{name: 'Venezuela', value: 236.299},
  							{name: 'Vietnam', value: 89047.397},
  							{name: 'Vanuatu', value: 236.299},
  							{name: 'West Bank', value: 13.565},
  							{name: 'Yemen', value: 22763.008},
  							{name: 'South Africa', value: 51452.352},
  							{name: 'Zambia', value: 13216.985},
  							{name: 'Zimbabwe', value: 13076.978}
  						]
  					}
  				]
  			};
  
  			myChart.setOption(option);
  
  
  
  			window.onresize = myChart.resize;
  		}
  	};
  	return directive;
  }
  /**
   *
   *
   */
  angular.module('MRT').directive('d3MapChart', d3MapChart);
  
  function d3MapChart($parse, $timeout) {
  	var directive = {
  		restrict: 'AE',
  		// templateUrl: 'pension/tpls/term/term-search-pageview.html',
  		replace: true,
  		//our data source would be an array
  		//passed thru chart-data attribute
  		scope: {options: '=options', clickEvent: '='},
  		link: function(scope, element, attrs) {
  
  			var centered;
  			var width = element[0].offsetWidth;
  			var height = 500;
  			var options = scope.options;
  			//console.log(options);
  
  			var map = new Datamap({
          scope: 'world',
          element: element[0],
          // projection: 'mercator',
  				/** setProjection: function(element) {
      var projection = d3.geo.equirectangular()
        .center([23, -3])
        .rotate([4.4, 0])
        .scale(400)
        .translate([element.offsetWidth / 2, element.offsetHeight / 2]);
      var path = d3.geo.path()
        .projection(projection);
  
      return {path: path, projection: projection};
    },**/
          height: 500,
          fills: {
            defaultFill: '#dadbdd',
            selectedFill: '#7ed6e0',
            gt50: '#7ed6e0'
          },
          data: {},
  				done: function(datamap) {
              datamap.svg.selectAll('.datamaps-subunit').on('click', function(geography) {
  							//scope.$apply(function(self) {
      						scope.$apply(scope.clickEvent(geography.id));
    						//});
  							// scope.clickEvent(geography.id);
  							// console.log(scope.clickEvent);
                  // alert(geography.properties.name);
  							//	clicked(geography, datamap.svg);
  							// console.log(geography);
              });
          }
        });
  
  			function clicked(d, g) {
  				// console.log(d);
    var x, y, k;
  
    if (d && centered !== d) {
      var centroid = map.path.centroid(d);
      x = centroid[0];
      y = centroid[1];
      k = 4;
      centered = d;
    } else {
      x = width / 2;
      y = height / 2;
      k = 1;
      centered = null;
    }
  
    g.selectAll("path")
        .classed("datamap", centered && function(d) { return d === centered; });
  
    g.transition()
        .duration(750)
        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
        .style("stroke-width", 1.5 / k + "px");
  }
  
  
        //sample of the arc plugin
        /**map.arc([
         {
          origin: {
              latitude: 40.639722,
              longitude: 73.778889
          },
          destination: {
              latitude: 37.618889,
              longitude: -122.375
          }
        },
        {
            origin: {
                latitude: 30.194444,
                longitude: -97.67
            },
            destination: {
                latitude: 25.793333,
                longitude: -0.290556
            }
        }
        ], {strokeWidth: 2});**/
  
  
         //bubbles, custom popup on hover template
  			 /**
       map.bubbles([
         {name: 'Hot', latitude: 21.32, longitude: 5.32, radius: 10, fillKey: 'gt50'},
         {name: 'Chilly', latitude: -25.32, longitude: 120.32, radius: 18, fillKey: 'lt50'},
         {name: 'Hot again', latitude: 21.32, longitude: -84.32, radius: 8, fillKey: 'gt50'},
  
       ], {
         popupTemplate: function(geo, data) {
           return "<div class='hoverinfo'>It is " + data.name + "</div>";
         }
       });**/
  
  
  
  
  		 scope.$watch('options.updated', function() {
  
  						 $timeout(function() {
  							 console.log("changed");
  							 console.log(options.data);
  							map.updateChoropleth(options.data);
  
  
  					}, 250); // delay 250 ms
  
  		 });
  
  		}
  	};
  
  	return directive;
  }
  ;
  
  /**
   * 
   * 
   */
  angular.module('MRT').directive('lineChart', lineChart);
  
  function lineChart($parse) {
      var directive = {
          restrict: 'AE',
          // templateUrl: 'pension/tpls/term/term-search-pageview.html',
          replace: true,
          //our data source would be an array
          //passed thru chart-data attribute
         // scope: {data: '=chartData'},
          link: function(scope, element, attrs) {
  
              var chart;
              d3.json('../data/cumulativeLineData.json', function(data) {
                  nv.addGraph(function() {
                      chart = nv.models.cumulativeLineChart()
                              .x(function(d) {
                          return d[0]
                      })
                              .y(function(d) {
                          return d[1] / 100
                      }) //adjusting, 100% is 1.00, not 100 as it is in the data
                              .color(d3.scale.category10().range())
                              .useInteractiveGuideline(true)
                              ;
  
                      chart.xAxis
                              .tickValues([1078030800000, 1122782400000, 1167541200000, 1251691200000])
                              .tickFormat(function(d) {
                          return d3.time.format('%x')(new Date(d))
                      });
  
                      chart.yAxis
                              .tickFormat(d3.format(',.1%'));
  
                      var svg = d3.select(element[0]).append('svg');
                      console.log(svg);
                              svg.datum(data)
                              .call(chart);
  
                      //TODO: Figure out a good way to do this automatically
                      nv.utils.windowResize(chart.update);
  
                      return chart;
                  });
              });
          }
      };
      return directive;
  }
  ;
  
  /**
   *
   * http://jsfiddle.net/pnavarrc/Sg3BY/1/
   */
  angular.module('MRT').directive('matrixChart', matrixChart);
  
  function matrixChart($parse) {
  	var directive = {
  		restrict: 'AE',
  		// templateUrl: 'pension/tpls/term/term-search-pageview.html',
  		replace: true,
  		//our data source would be an array
  		//passed thru chart-data attribute
  		// scope: {data: '=chartData'},
  		link: function(scope, element, attrs) {
  
  			var colors = {
  				'1_1' : '#E75C3D',
  				'1_2' : '#E75C3D',
  				'1_3' : '#FBC226',
  				'2_1' : '#E75C3D',
  				'2_2' : '#FBC226',
  				'2_3' : '#63C954',
  				'3_1' : '#FBC226',
  				'3_2' : '#63C954',
  				'3_3' : '#63C954',
  				'yellow': '#FBC226',
  				'blue': '#3598DB',
  				'green': '#63C954',
  				'red': '#E75C3D',
  				'hoverbg': '#394855',
  				'label': '#394855'
  			};
  
  			var countries = ['Gambia', 'Senegal', 'Mali', 'Egypt', 'Sierra Leone', 'Nigeria', 'Ghana', 'South Africa'];
  			var options = {
  				x: {
  					key: "x",
  					label : 'Business Unit Strength',
  					cells: [
  						{label: 'Low', key: "low"},
  						{label: 'Medium', key: "medium"},
  						{label: 'High', key: "high"}
  					]
  				},
  				y: {
  					key: "x",
  					label : 'Industry Attractiveness',
  					cells: [
  						{label: 'Low', key: "low"},
  						{label: 'Medium', key: "medium"},
  						{label: 'High', key: "high"}
  					]
  				}
  			};
  
  		var marginLeft = 100;
  		var marginTop = 100;
  		var outerWidth = element[0].offsetWidth;
  		var outerHeight = 600;
  		var width = outerWidth-marginLeft;
  		var height = outerHeight-marginTop;
  
  		console.log(outerWidth);
  		console.log(width);
  
      var div = d3.select(element[0]).style("fill", "#E2E2E2");
  
      var svg = div.append('svg')
          .attr('width', outerWidth)
          .attr('height', outerHeight);
  				var xTitle = svg.append("g")
  								.attr('transform', function(d, i) {
  						        return 'translate(' + marginLeft +', ' + (marginTop/2)*0 + ')';
  						    })
  								.append("text");
  
  				xTitle.attr("x", function() {
  									return width/2;
  								})
  								.attr("y", function() {
  									return 20;
  								})
  								.style("font-size", "20px")
  								.style("text-anchor", "middle")
  		            .attr("fill", colors['label'])
  								.text("Business Unit Strength");
  
  
  
  
  
  		var chart = svg.append("g");
  				chart.attr('transform', function(d, i) {
  		        return 'translate(' + marginLeft +', ' + marginTop + ')';
  		    });
  
  
  		var xLabels = svg.append("g")
  										.attr('transform', function(d, i) {
  								        return 'translate(' + marginLeft +', ' + (marginTop/2)*1 + ')';
  								    });
  
  
  		var xCells = options.x.cells.length;
  		var yCells = options.y.cells.length;
  
  
  		function shadeColor(color, percent) {
      var f=parseInt(color.slice(1),16),t=percent<0?0:255,p=percent<0?percent*-1:percent,R=f>>16,G=f>>8&0x00FF,B=f&0x0000FF;
      return "#"+(0x1000000+(Math.round((t-R)*p)+R)*0x10000+(Math.round((t-G)*p)+G)*0x100+(Math.round((t-B)*p)+B)).toString(16).slice(1);
  }
  
  function blendColors(c0, c1, p) {
      var f=parseInt(c0.slice(1),16),t=parseInt(c1.slice(1),16),R1=f>>16,G1=f>>8&0x00FF,B1=f&0x0000FF,R2=t>>16,G2=t>>8&0x00FF,B2=t&0x0000FF;
      return "#"+(0x1000000+(Math.round((R2-R1)*p)+R1)*0x10000+(Math.round((G2-G1)*p)+G1)*0x100+(Math.round((B2-B1)*p)+B1)).toString(16).slice(1);
  }
  
  
  
  var data = [];
  for (var k = 0; k < yCells; k++) {
  		var row = [];
  		var yId = yCells-k;
  		for (var i = 0; i < xCells; i++) {
  			var xId = i+1;
  			var cell = {};
  			cell.id = xId + '_' + yId;
  			cell.data = angular.copy(countries);
  			row.push(cell);
  		}
      data.push(row);
  }
  
  function rotate(d, w) {
             return "rotate(-90) translate(" +
                         (-d.dy / 2) +
                         ", " +
                         (w / 2 + 5) +
         ")";
  }
  var x = d3.scale.ordinal().rangeRoundBands([ 0, width ], 0.009, 0);
  var y = d3.scale.ordinal().rangeRoundBands([ 0, height ], 0.009, 0);
  x.domain(d3.range(xCells));
  y.domain(d3.range(yCells));
  
  // Create a group for each row in the data matrix and
  // translate the group vertically
  var row = chart.selectAll('.row')
      .data(data)
      .enter()
      .append('g')
  		.attr('class', 'row')
      .attr('transform', function(d, i) {
          return 'translate(0, ' + y(i) + ')';
      });
  
  
  // For each group, create a set of rectangles and bind
  // them to the inner array (the inner array is already
  // binded to the group)
  var cell = row.selectAll('.cell')
      .data(function(d) { return d; })
      .enter()
  		.append("g")
  	.attr("class", "card-group")
  	.attr('transform', function(d, i) {
  			return 'translate(' + x(i) + ', ' + 0 + ')';
  	});
  
  
  	cell.append('rect')
  		.attr('class', 'cell')
       .attr('x', function(d, i) { return 0; return x(i); })
          .attr('width', x.rangeBand())
          .attr('height', y.rangeBand())
  				.style('fill', function(d) {
  					return colors[d.id];
  				})
  				;
  
  				cell
  						.append("svg:foreignObject")
  						.attr('x', function(d, i) { return 0; return x(i); })
  						.attr('width', x.rangeBand())
  						.attr('height', y.rangeBand())
  						.attr('class', 'text-group')
  						.append("xhtml:div")
  						    .style("font-size", "10px")
  								.style('height', '100%')
  								.style("background-color", "transparent")
  								.style("text-anchor", "middle")
  								.style("color", function(d) {
  									return '#546678';
  									return  colors[d.id];
  								})
  								.style("text-align", "center")
  								.style("padding", "5%")
  							//	.style("position", "relative")
  								// .style("top", "50%")
  								// .style("translate", "translateY(-50%)")
  						    .html(function(d) {
  									var html = "";
  									var color = shadeColor( colors[d.id], 0.5);
  									for(var c = 0; c < d.data.length; c++) {
  										html = html + "<span style='border-radius: 2px; border: 5px solid " + color + ";padding: 2px; background-color: #fff; display: inline-block; margin: 2px;'>" + d.data[c] + "</span>";
  									}
  									return html;
  								})
  
  								;
  
  
  
  
  
  		}
  	};
  	return directive;
  };
  
  /**
   * 
   * 
   */
  angular.module('MRT').directive('mrtChart', mrtChart);
  
  function mrtChart($parse, $timeout) {
  	var directive = {
  		// templateUrl: 'pension/tpls/term/term-search-pageview.html',
  		replace: true,
  		scope: {chartData: '=chartData'},
  		link: function(scope, element, attrs) {
  
  			var myChart = echarts.init(element[0]);
  			var chartData = scope.chartData;
  
  			myChart.showLoading({
  				text: "We're building the buildings as fast as we can...please wait! ", //loading text
  			});
  
  			myChart.hideLoading();
  
  
  			function updateChartOptions() {
  				if(typeof chartData.xAxis === 'undefined') {
  					myChart.setOption(chartData, true);
  				} else if(typeof chartData.xAxis[0].data !== 'undefined' && chartData.xAxis[0].data.length) {
  					// console.log(chartData);
  					myChart.setOption(chartData, true);
  					myChart.refresh();
  					myChart.resize();
  					myChart.restore();
  					
  				}
  			}
  
  			scope.$watch('chartData.updatedAt', function() { 
  				$timeout(function() {
              updateChartOptions();
          }, 250); // delay 250 ms
  				
  			});
  
  			window.onresize = function() {
  				myChart.resize();
  			};
  		}
  	};
  	return directive;
  }
  /**
   * 
   * 
   */
  angular.module('MRT').directive('mrtLineChart', mrtLineChart);
  
  function mrtLineChart($parse) {
  	var directive = {
  		// templateUrl: 'pension/tpls/term/term-search-pageview.html',
  		replace: true,
  		scope: {chartData: '=chartData'},
  		link: function(scope, element, attrs) {
  
  			var myChart = echarts.init(element[0]);
  
  			myChart.showLoading({
  				text: "We're building the buildings as fast as we can...please wait! ", //loading text
  			});
  
  // ajax getting data...............
  
  // ajax callback
  			myChart.hideLoading();
  
  // use the chart-------------------
  			var option = {
  				legend: {// legend configuration
  					// padding: 5, // The inner padding of the legend, in px, defaults to 5. Can be set as array - [top, right, bottom, left].
  					//itemGap: 10, // The pixel gap between each item in the legend. It is horizontal in a legend with horizontal layout, and vertical in a legend with vertical layout. 
  					data: ['usd', 'gbp']
  				},
  				tooltip: {// tooltip configuration
  					trigger: 'item', // trigger type. Defaults to data trigger. Can also be: 'axis'
  				},
  				xAxis: [// The horizontal axis in Cartesian coordinates
  					{
  						type: 'category', // Axis type. xAxis is category axis by default. As for value axis, please refer to the 'yAxis' chapter.
  						data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
  					}
  				],
  				yAxis: [// The vertical axis in Cartesian coordinates
  					{
  						type: 'value', // Axis type. yAxis is value axis by default. As for category axis, please refer to the 'xAxis' chapter.
  						//boundaryGap: [0.1, 0.1], // Blank border on each side of the coordinate axis. Value in the array represents percentage. 
  						splitNumber: 4                      // Applicable to value axis. The number of segments. Defaults to 5. 
  					}
  				],
  				series: [
  					{
  						name: 'usd', // series name
  						type: 'line', // chart type, line, scatter, bar, pie, radar
  						 itemStyle: {normal: {areaStyle: {type: 'default'}}},
  						data: [112, 23, 45, 56, 233, 343, 454, 89, 343, 123, 45, 123]
  					},
  					{
  						name: 'gbp', // series name
  						type: 'line', // chart type, line, scatter, bar, pie, radar
  						data: [45, 123, 145, 526, 233, 343, 44, 829, 33, 123, 45, 13]
  					}
  				]
  			};
  			myChart.setOption(option);
  
  
  // Add some data------------------
  			option.legend.data.push('win');
  			option.series.push({
  				name: 'win', // series name
  				type: 'line', // chart type, line, scatter, bar, pie, radar
  				data: [112, 23, 45, 56, 233, 343, 454, 89, 343, 123, 45, 123]
  			});
  
  			myChart.setOption(option);
  		}
  	};
  	return directive;
  }
  /**
   * 
   * 
   */
   angular.module('MRT').directive('mrtMapChart', mrtMapChart);
  
   function mrtMapChart($parse, $timeout) {
   	var directive = {
   		restrict: 'AE',
  		// templateUrl: 'pension/tpls/term/term-search-pageview.html',
  		replace: true,
  		//our data source would be an array
  		//passed thru chart-data attribute
  		scope: {chartData: '=chartData'},
  		link: function(scope, element, attrs) {
  // // instantiate the chart------------------
  // script plain import
  var myChart = echarts.init(element[0]);
  
  
  // loading---------------------
  myChart.showLoading({
  				text: "We're building the buildings as fast as we can...please wait! ", //loading text
  			});
  
  // ajax getting data...............
  
  // ajax callback
  myChart.hideLoading();
  
  myChart.on('DATA_CHANGED', function() {
  	console.log('data changed');
  });
  
  
  function updateChartOptions() {
  	var chartData = scope.chartData;
  	console.log('directive render : ' + chartData.title.text);
  	// console.log(chartData.series[0].data);
  
  				// use the chart-------------------
  				option = {
  					title: {
  						text: chartData.title.text,
  						subtext: chartData.title.subtext,
  					// sublink: 'http://esa.un.org/wpp/Excel-Data/population.htm',
  					x: 'center',
  					y: 'top'
  				},
  				tooltip: {
  					trigger: 'item',
  					formatter: function(params) {
  						var value = (params.value + '').split('.');
  						value = value[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g, '$1,')
  						+ '.' + value[1];
  						return params.seriesName + '<br/>' + params.name + ' : ' + value;
  					}
  				},
  				toolbox: {
  					show: true,
  					orient: 'vertical',
  					x: 'right',
  					y: 'center',
  					feature: {
  						mark: {
  							show: true,
  							title: 'Mark',
  						},
  						dataView: {
  							show: true,
  							title: 'View Data',
  							readOnly: true,
  							lang: ['View Data', 'Close', 'Refresh']
  						},
  						restore: {
  							show: true,
  							title: 'Restore',
  						},
  						saveAsImage: {
  							show: true,
  							title: 'Save As Image',
  							type: 'png',
  							lang: ['Language']
  						}
  					}
  				},
  				dataRange: chartData.dataRange,
  				series: chartData.series
  			};
  			myChart.setOption(option, true);
  								myChart.refresh();
  					myChart.resize();
  					myChart.restore();
  			// myChart.refresh();
  			// myChart.setSeries(option.series);
  
  		};
  
  		updateChartOptions();
  
  
  
  		scope.$watch('chartData.series[0].data', function() { 
  
  						$timeout(function() {
              updateChartOptions();
          }, 250); // delay 250 ms
  			
  		});
  
  		window.onresize = function() {
  			myChart.resize();
  		};
  
  
  	}
  };
  return directive;
  }
  /**
   *
   *
   */
  angular.module('MRT').directive('pieChart', pieChart);
  
  function pieChart($parse) {
  	var directive = {
  		restrict: 'AE',
  		// templateUrl: 'pension/tpls/term/term-search-pageview.html',
  		replace: true,
  		//our data source would be an array
  		//passed thru chart-data attribute
  		// scope: {data: '=chartData'},
  		link: function(scope, element, attrs) {
  
  			var dataset = {
  				apples: [
  					{name: 'The Gambia', value: 53245},
  					{name: 'Senegal', value: 28479},
  					{name: 'Sierra Leone', value: 19697},
  					{name: 'Nigeria', value: 24037},
  					{name: 'Liberia', value: 40245}
  				]
  			};
  			/**
  			 var dataset = {
  			 apples: [53245, 28479, 19697, 24037, 40245],
  			 };
  			 **/
  			var width = 300,
  					height = 300,
  					radius = Math.min(width, height) / 2;
  
  			var color = d3.scale.category20();
  // console.log(color);
  			var color2 = ['#3498db', '#2ecc71', '#2c3e50', '#8e44ad', '#f39c12', '#e74c3c'];
  			var color2 = ['#00BFF3', '#EB5367', '#FFCE54', '#738F12', '#2A2F36']
  			var hex = color2[0];
  
  			var colorLighter= d3.scale.linear().domain([0,dataset.apples.length])
        .range([d3.rgb(hex), d3.rgb('#c9e9f5')]);
  	  // d3.rgb(hex).brighter(1)
  			var pie = d3.layout.pie()
  					.value(function(d) {
  						return d.value;
  					})
  					.sort(null);
  
  			var piedata = pie(dataset.apples);
  
  			var arc = d3.svg.arc()
  					.innerRadius(radius - (width / 3))
  					.outerRadius(radius - (width / 6));
  
  
  			var svg = d3.select(element[0]).append('svg')
  					.attr("width", width)
  					.attr("height", height)
  					.append("g")
  					.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
  
  			var path = svg.selectAll("path")
  					.data(piedata)
  					.enter().append("path")
  					.attr("fill", function(d, i) {
  						// return color2[i];
  						return colorLighter(i);
  					})
  					.attr("d", arc);
  
  			svg.selectAll("text").data(piedata)
  					.enter()
  					.append("text")
  					.style("fill", "#7f8c8d")
  					.attr("text-anchor", "middle")
  					.attr("x", function(d) {
  						// console.log(d);
  						var a = d.startAngle + (d.endAngle - d.startAngle) / 2 - Math.PI / 2;
  						d.cx = Math.cos(a) * (radius - 75);
  						return d.x = Math.cos(a) * (radius - 20);
  					})
  					.attr("y", function(d) {
  						var a = d.startAngle + (d.endAngle - d.startAngle) / 2 - Math.PI / 2;
  						d.cy = Math.sin(a) * (radius - 75);
  						return d.y = Math.sin(a) * (radius - 20);
  					})
  					.text(function(d) {
  						return d.data.name;
  					})
  					.each(function(d) {
  						var bbox = this.getBBox();
  						d.sx = d.x - bbox.width / 2 - 2;
  						d.ox = d.x + bbox.width / 2 + 2;
  						d.sy = d.oy = d.y + 5;
  					});
  
  			svg.append("defs").append("marker")
  					.attr("id", "circ")
  					.attr("markerWidth", 6)
  					.attr("markerHeight", 6)
  					.attr("refX", 3)
  					.attr("refY", 3)
  					.style("fill", "#7f8c8d")
  					.append("circle")
  					.attr("cx", 3)
  					.attr("cy", 3)
  					.attr("r", 3);
  
  			svg.selectAll("path.pointer").data(piedata).enter()
  					.append("path")
  					.attr("class", "pointer")
  					.style("fill", "none")
  					.style("stroke", "#7f8c8d")
  					.attr("marker-end", "url(#circ)")
  					.attr("d", function(d) {
  						if (d.cx >= d.ox) {
  							return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
  						} else {
  							// console.log(d);
  							return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
  						}
  					});
  
  
  		}
  	};
  	return directive;
  }
  ;
  
  /**
  *
  *
  */
  angular.module('MRT').directive('vsModelChart', vsModelChart);
  
  function vsModelChart($parse, $timeout, $interval) {
  	var directive = {
  		// templateUrl: 'pension/tpls/term/term-search-pageview.html',
  		replace: true,
  		scope: {data: '=data', playing: '=playing'},
  		link: function(scope, element, attrs) {
  
  			// Various accessors that specify the four dimensions of data to visualize.
  			function x(d) { return d['x-axis']; }
  			function y(d) { return d['y-axis']; }
  			function radius(d) { return d['bubble-size']; }
  			function color(d) { return d['name']; }
  			function key(d) { return d.name; }
  
  			// Chart dimensions.
  			var svg;
  			var xAxis;
  			var yAxis;
  			var margin;
  			var width;
  			var height;
  			var xScale;
  			var yScale;
  			var radiusScale;
  			var colorScale;
  			var label;
  			var countrylabel;
  			var bisect = d3.bisector(function(d) { return d[0]; });
  
  			var first_time = true;
  			var outerWith = element[0].clientWidth-100;
  			function prep(axis) {
  			margin = {top: 19.5, right: 19.5, bottom: 19.5, left: 39.5}
  			width = outerWith - margin.right;
  			height = 500 - margin.top - margin.bottom;
  
  			// Various scales. These domains make assumptions of data, naturally.
  			xScale = d3.scale.log().domain([axis['x-axis'].minValue, axis['x-axis'].maxValue]).range([0, width]);
  			yScale = d3.scale.linear().domain([10, axis['y-axis'].maxValue]).range([height, 0]);
  			radiusScale = d3.scale.sqrt().domain([0, axis['bubble-size'].maxValue]).range([0, 40]),
  			colorScale = d3.scale.category10();
  			var colorScaleTheme = function() {
    		 return d3.scale.ordinal().range(['rgba(52, 152, 219,1.0)', 'rgba(142, 68, 173,1.0)', 'rgba(46, 204, 113,1.0)', 'rgba(44, 62, 80,1.0)', 'rgba(230, 126, 34,1.0)', 'rgba(41, 128, 185,1.0)', 'rgba(231, 76, 60,1.0)', 'rgba(127, 140, 141,1.0)']);
  			};
  			colorScale = colorScaleTheme();
  
  			// The x & y axes.
  			xAxis = d3.svg.axis().orient("bottom").scale(xScale).ticks(12, d3.format(",d")),
  			yAxis = d3.svg.axis().scale(yScale).orient("left");
  
  			// Create the SVG container and set the origin.
  			svg = d3.select(element[0]).html("").append("svg")
  			.attr("width", width + margin.left + margin.right)
  			.attr("height", height + margin.top + margin.bottom)
  			.append("g")
  			.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
  			.attr("class", "gRoot")
  
  			// Add the x-axis.
  			svg.append("g")
  			.attr("class", "x axis")
  			.attr("transform", "translate(0," + height + ")")
  			.call(xAxis);
  
  			// Add the y-axis.
  			svg.append("g")
  			.attr("class", "y axis")
  			.call(yAxis);
  
  			// Add an x-axis label.
  			svg.append("text")
  			.attr("class", "x label")
  			.attr("text-anchor", "end")
  			.attr("x", width)
  			.attr("y", height - 6)
  			.text(axis['x-axis'].name);
  
  			// Add a y-axis label.
  			svg.append("text")
  			.attr("class", "y label")
  			.attr("text-anchor", "end")
  			.attr("y", 6)
  			.attr("dy", ".75em")
  			.attr("transform", "rotate(-90)")
  			.text(axis['y-axis'].name);
  
  			// Add the year label; the value is set on transition.
  			label = svg.append("text")
  			.attr("class", "year label")
  			.attr("text-anchor", "end")
  			.attr("y", height - 24)
  			.attr("x", width)
  			.text(axis.max);
  
  			// Add the country label; the value is set on transition.
  			countrylabel = svg.append("text")
  			.attr("class", "country label")
  			.attr("text-anchor", "start")
  			.attr("y", 80)
  			.attr("x", 20)
  			.text(" ");
  
  
  		}
  
  			// Load the data.
  			//d3.json("http://romsson.github.io/dragit/data/nations.json", function(nations) {
  				// draw(nations);
  			// });
  
  			function draw(nations, axis) {
  
  
  
  				function interpolateData(year) {
  					var r = nations.map(function(d) {
  						var rt = {
  							year: year,
  							name: d.name,
  							region: d.name,
  							'x-axis': interpolateValues(d['x-axis'], year),
  							'bubble-size': interpolateValues(d['bubble-size'], year),
  							'y-axis': interpolateValues(d['y-axis'], year)
  						};
  						return rt;
  					});
  
  					return r.filter(function(d) {
  						return d['x-axis'] && d['y-axis'] && d['bubble-size'];
  					});
  				}
  
  
  
  				// Finds (and possibly interpolates) the value for the specified year.
  				function interpolateValues(values, year) {
  					var i = bisect.left(values, year, 0, values.length - 1),
  					a = values[i];
  					if (i > 0) {
  						var b = values[i - 1],
  						t = (year - a[0]) / (b[0] - a[0]);
  						return a[1] * (1 - t) + b[1] * t;
  					}
  
  					return a && typeof a[1] !== 'undefined' ? a[1] : null;
  				}
  
  				//console.log(nations);
  				//console.log(interpolateData(2013));
  
  
  				// return;
  				prep(axis);
  				// var nations = [];
  				// A bisector since many nation's data is sparsely-defined.
  
  
  				// Add a dot per nation. Initialize the data at 1800, and set the colors.
  				var dot = svg.append("g")
  				.attr("class", "dots")
  				.selectAll(".dot")
  				.data(interpolateData(axis.max))
  				.enter().append("circle")
  				.attr("class", "dot")
  				.style("fill", function(d) { return colorScale(color(d)); })
  				.call(position)
  				.on("mousedow", function(d, i) {
  
  				})
  				.on("mouseup", function(d, i) {
  					dot.classed("selected", false);
  					d3.select(this).classed("selected", !d3.select(this).classed("selected"));
  					dragit.trajectory.display(d, i, "selected");
  
  					//TODO: test if has been dragged
  					// Look at the state machine history and find a drag event in it?
  
  				})
  				.on("mouseenter", function(d, i) {
  					clear_demo();
  					if(dragit.statemachine.current_state == "idle") {
  						dragit.trajectory.display(d, i)
  						dragit.utils.animateTrajectory(dragit.trajectory.display(d, i), dragit.time.current, 1000)
  						countrylabel.text(d.name);
  						dot.style("opacity", .4)
  						d3.select(this).style("opacity", 1)
  						d3.selectAll(".selected").style("opacity", 1)
  					}
  				})
  				.on("mouseleave", function(d, i) {
  
  					if(dragit.statemachine.current_state == "idle") {
  						countrylabel.text("");
  						dot.style("opacity", 1);
  					}
  
  					dragit.trajectory.remove(d, i);
  				})
  				.call(dragit.object.activate)
  
  				// Add a title.
  				dot.append("title")
  				.text(function(d) { return d.name; });
  
  				// Start a transition that interpolates the data based on year.
  				svg.transition()
  				.duration(30000)
  				.ease("linear")
  
  				// Positions the dots based on data.
  				function position(dot) {
  					dot.attr("cx", function(d) {
  						var r = xScale(x(d));
  						//if(r === '-Infinity') {
  						// console.log(d);
  						//}
  						return r;
  					})
  					.attr("cy", function(d) { return yScale(y(d)); })
  					.attr("r", function(d) { return radiusScale(radius(d)); });
  				}
  
  				// Defines a sort order so that the smallest dots are drawn on top.
  				function order(a, b) {
  					return radius(b) - radius(a);
  				}
  
  				// Updates the display to show the specified year.
  				function displayYear(year) {
  					dot.data(interpolateData(year+dragit.time.min), key).call(position).sort(order);
  					label.text(dragit.time.min + Math.round(year));
  				}
  
  
  				// Interpolates the dataset for the given (fractional) year.
  
  				init();
  
  				function update(v, duration) {
  					dragit.time.current = v || dragit.time.current;
  					displayYear(dragit.time.current)
  					console.log(dragit.time.current);
  					d3.select("#slider-time").property("value", dragit.time.current);
  				}
  
  
  
  				function init() {
  
  
  					dragit.init(".gRoot");
  
  					dragit.time = {min:axis.min, max: axis.max, step:1, current: axis.min}
  					dragit.data = d3.range(nations.length).map(function() { return Array(); })
  
  					for(var yy = axis.min; yy<axis.max; yy++) {
  
  						interpolateData(yy).filter(function(d, i) {
  							dragit.data[i][yy-dragit.time.min] = [xScale(x(d)), yScale(y(d))];
  						});
  					}
  
  					dragit.evt.register("update", update);
  
  					d3.select("#slider-time").property("value", dragit.time.current);
  
  					d3.select("#slider-time")
  					.on("mousemove", function() {
  						update(parseInt(this.value), 500);
  						clear_demo();
  					})
  
  					var end_effect = function() {
  						countrylabel.text("");
  						dot.style("opacity", 1)
  					}
  
  				//	dragit.evt.register("dragend", end_effect)
  				}
  
  				function clear_demo() {
  					if(first_time) {
  						svg.transition().duration(0);
  						first_time = false;
  						window.clearInterval(demo_interval);
  						countrylabel.text("");
  						dragit.trajectory.removeAll();
  						d3.selectAll(".dot").style("opacity", 1)
  					}
  				}
  
  				var demo_interval = null;
  
  				var playing = false;
  
  				var stopTime;
  				function play() {
  
  					var el = document.getElementById("slider-time");
  					var min = parseInt(d3.select("#slider-time").attr("min"));
  					var max = parseInt(scope.data.axis.max-scope.data.axis.min);
  
  					// console.log();
  					var step = parseInt(d3.select("#slider-time").attr("step"));
  					stopTime = $interval(function() {
  						stepFn(min, max, step, el, update);
  					}, 100);
  
  				}
  
  				function stepFn(min, max, step, el, update) {
  					if(scope.playing !== true) {
  						return false;
  					}
  					var value = parseInt(el.value);
  					// console.log("value  " + value);
  					value = (value+step <= max) ? value+step : min;
  					if(value === 0) {
  						value = 1;
  					}
  					console.log("value + " + value);
  					el.value = value;
  					update(parseInt(value), 500);
  					clear_demo();
  					console.log("playing " + value);
  					console.log("max " + max);
  					console.log("step " + step);
  
  				}
  
  				play();
  
  
  			}
  
  
  
  			scope.$watch('data', function(newValue, oldValue) {
  				// console.log(newValue);
  				if(newValue && typeof newValue.data !== "undefined") {
  					// console.log(newValue.axis);
  
  					draw(newValue.data, newValue.axis);
  				}
  
  			}, true);
  		}
  	};
  	return directive;
  }
  
  /**
   * 
   * 
   */
  angular.module('MRT').directive('worldMap', worldMap);
  
  function worldMap($parse) {
      var directive = {
          restrict: 'AE',
          // templateUrl: 'pension/tpls/term/term-search-pageview.html',
          replace: true,
          //our data source would be an array
          //passed thru chart-data attribute
          scope: {data: '=chartData'},
          link: function(scope, element, attrs) {
              //in D3, any selection[0] contains the group
              //selection[0][0] is the DOM node
              //but we won't need that this time
              // var selector = element[0];
              var chart;
              //var color = d3.scale.linear().domain([0,1]).range(["#fed900","#39c"]);
              var color = ["#fed900", "#39c"];
  
              // console.log("log");
              // var $container = "container";
              var $element = element[0];
              var $topoUrl = "../data/world-topo-min.json";
              var $dataUrl = "../data/country-capitals.csv";
  
              d3.select(window).on("resize", throttle);
  
              var zoom = d3.behavior.zoom()
                      .scaleExtent([1, 9])
                      .on("zoom", move);
  
  
              var width = $element.offsetWidth;
              var height = width / 4;
  // var height = width / 4;
  
              var topo, projection, path, svg, g;
  
              var graticule = d3.geo.graticule();
  
              var tooltip = d3.select($element).append("div").attr("class", "tooltip hidden");
  
              setup(width, height);
  
              function setup(width, height) {
                  projection = d3.geo.mercator()
                          .translate([(width / 2), (height / 2)])
                          .scale(width / 2 / Math.PI);
  
                  path = d3.geo.path().projection(projection);
  
                  svg = d3.select($element).append("svg")
                          .attr("width", width)
                          .attr("height", height)
                          .call(zoom)
                          .on("click", click)
                          .append("g");
  
                  g = svg.append("g");
  
              }
  
              d3.json($topoUrl, function(error, world) {
  
                  var countries = topojson.feature(world, world.objects.countries).features;
  
                  topo = countries;
                  draw(topo);
  
              });
  
  
              function getColours(r, g, b) {
                  var opc = 0.1;
                  var colours = [];
                  while (opc <= 1) {
                      colours.push("rgba(" + r + ", " + g + ", " + b + ", " + opc + ")");
                      opc += 0.1;
                  }
                  return colours;
              }
  
  // var colours = getColours(41, 125, 185);
  // var colours = getColours(52, 152, 219);
              var colours = getColours(243, 156, 18);
              var colours = getColours(243, 156, 18);
  
  
              var heatmapColour = d3.scale.linear()
                      .domain(d3.range(0, 1, 1.0 / (colours.length - 1)))
                      .range(colours);
  
              function draw(topo) {
  
                  svg.append("path")
                          .datum(graticule)
                          .attr("class", "graticule")
                          .attr("d", path);
  
  
                  g.append("path")
                          .datum({type: "LineString", coordinates: [[-180, 0], [-90, 0], [0, 0], [90, 0], [180, 0]]})
                          .attr("class", "equator")
                          .attr("d", path);
  
  
                  var country = g.selectAll(".country").data(topo);
  
                  country.enter().insert("path")
                          .attr("class", "country")
                          .attr("d", path)
                          .attr("id", function(d, i) {
                      return d.id;
                  })
                          .attr("title", function(d, i) {
                      return d.properties.name;
                  })
                          .attr("country", function(d, i) {
                      return d.properties.name.toUpperCase();
                  })
                          .style("fill", function(d, i) {
                      return '#ccc';
                  });
  
                  //offsets for tooltips
                  var offsetL = $element.offsetLeft + 20;
                  var offsetT = $element.offsetTop + 10;
  
                  //tooltips
                  country
                          .on("mousemove", function(d, i) {
  
                      var mouse = d3.mouse(svg.node()).map(function(d) {
                          return parseInt(d);
                      });
  
                      tooltip.classed("hidden", false)
                              .attr("style", "left:" + (mouse[0] + offsetL) + "px;top:" + (mouse[1] + offsetT) + "px")
                              .html(d.properties.name);
  
                  })
                          .on("mouseout", function(d, i) {
                      tooltip.classed("hidden", true);
                  });
  
  
  
                  //EXAMPLE: adding some capitals from external CSV file
                  d3.csv($dataUrl, function(err, capitals) {
  
                      capitals.forEach(function(i) {
                          addpoint(i.CapitalLongitude, i.CapitalLatitude, i.CapitalName);
                          var percent = i.Percent;
                          var rgb = d3.rgb('#090');
                          //console.log(i.CountryName.toUpperCase());
                          d3.select("[country='" + i.CountryName.toUpperCase() + "']").style("fill", function(d) {
                              // console.log(rgb.toString());
                              return heatmapColour(percent);
                          });
                      });
  
                  });
  
              }
  
  
              function redraw() {
                  width = $element.offsetWidth;
                  height = width / 2;
                  d3.select('svg').remove();
                  setup(width, height);
                  draw(topo);
              }
  
  
              function move() {
  
                  var t = d3.event.translate;
                  var s = d3.event.scale;
                  zscale = s;
                  var h = height / 4;
  
  
                  t[0] = Math.min(
                          (width / height) * (s - 1),
                          Math.max(width * (1 - s), t[0])
                          );
  
                  t[1] = Math.min(
                          h * (s - 1) + h * s,
                          Math.max(height * (1 - s) - h * s, t[1])
                          );
  
                  zoom.translate(t);
                  g.attr("transform", "translate(" + t + ")scale(" + s + ")");
  
                  //adjust the country hover stroke width based on zoom level
                  d3.selectAll(".country").style("stroke-width", 1.5 / s);
  
              }
  
  
  
              var throttleTimer;
              function throttle() {
                  window.clearTimeout(throttleTimer);
                  throttleTimer = window.setTimeout(function() {
                      redraw();
                  }, 200);
              }
  
  
  //geo translation on mouse click in map
              function click() {
                  var latlon = projection.invert(d3.mouse(this));
                  console.log(latlon);
              }
  
  
  //function to add points and text to the map (used in plotting capitals)
              function addpoint(lat, lon, text) {
  
                  var gpoint = g.append("g").attr("class", "gpoint");
                  var x = projection([lat, lon])[0];
                  var y = projection([lat, lon])[1];
  
                  gpoint.append("svg:circle")
                          .attr("cx", x)
                          .attr("cy", y)
                          .attr("class", "point")
                          .attr("r", 1.5);
  
                  //conditional in case a point has no associated text
                  if (text.length > 0) {
  
                      gpoint.append("text")
                              .attr("x", x + 2)
                              .attr("y", y + 2)
                              .attr("class", "text")
                              .text(text);
                  }
  
              }
  
          }
      };
      return directive;
  }
  ;
  
  angular.module('MRT').controller('DashboardCtrl', ['$scope', '$filter', 'geoModelService', 'geoGroupService', function($scope, $filter, geoModelService, geoGroupService) {
  		$scope.app.loggedIn = true;
  }]);
  angular.module('MRT').controller('GeographyCtrl', ['$scope', '$filter', 'ngTableParams', 'geographyService', function($scope, $filter, ngTableParams, geographyService) {
  
          $scope.data = {};
          $scope.data.geographies = [];
          $scope.data.tableData = [];
  
  
          geographyService.getGeographies($scope.data.params).success(function(data) {
  
              $scope.data.geographies = data.geographies;
  
  
          }).error(function(error) {
              $scope.status = 'Unable to load customer data: ' + error.message;
  
          });
  
      }]);
  angular.module('MRT')
          .factory('geographyService', ['$http', 'env', function($http, env) {
  
  
          var urlBase = env.apiUrl;
          var dataFactory = {
              geographies: {}
          };
  
          dataFactory.getGeographies = function(params) {
              return $http.get(urlBase + '/geography/', {
                  params: params
              });
          };
  
  
  
  
  
          return dataFactory;
      }]);
  angular.module('MRT').controller('GeoGroupCtrl', ['$scope', '$filter', '$state', 'geoGroupService', function($scope, $filter, $state, geoGroupService) {
  
          $scope.data = {};
          $scope.data.filterText = '';
          $scope.search = '';
          $scope.data.geogroups = [];
  
          geoGroupService.list($scope.data.params).success(function(data) {
              $scope.data.geogroups = data.geogroups;
          }).error(function(error) {
              $scope.status = 'Unable to load customer data: ' + error.message;
          });
  
          $scope.getFilter = function() {
              return {name: $scope.data.filterText};
          };
  
          $scope.selected = function(item) {
              geoGroupService.data.selected = item;
          };
  
      }]).controller('GeoGroupViewCtrl', ['$scope', '$filter', '$stateParams', '$state', 'geoGroupService', 'geographyService', function($scope, $filter, $stateParams, $state, geoGroupService, geographyService) {
          $scope.data = {};
          $scope.templateVar = {};
  
  
          $scope.data.changed = false;
          $scope.data.geographies = [];
          $scope.data.geogroupgeographies = [];
          $scope.data.geogroup = {name: '', description: ''};
          $scope.data.params = {};
          $scope.data.params.id = $stateParams.id;
  
          geographyService.getGeographies($scope.data.params).success(function(data) {
              $scope.data.geographies = data.geographies;
              $scope.sortCountries();
              $scope.getGeographies();
  
          }).error(function(error) {
              $scope.status = 'Unable to load customer data: ' + error.message;
  
          });
  
          $scope.sortCountries = function() {
              $scope.data.geographies = $filter('orderBy')($scope.data.geographies, 'name');
          };
  
  
          $scope.changed = function() {
              $scope.data.changed = true;
          };
  
          // function to submit the form after all validation has occurred			
          $scope.submitForm = function(isValid) {
  
              // check to make sure the form is completely valid
              if (isValid) {
                  // alert('our form is amazing');
                  $scope.data.geogroup.geographies = [];
                  angular.forEach($scope.data.geographies, function(geography, key) {
                      if (!angular.isUndefined(geography.selected) && geography.selected === true) {
                          $scope.data.geogroup.geographies.push(geography);
                      }
                  });
  
                  geoGroupService.replaceGeographies($scope.data.geogroup).success(function(data) {
                      $state.go('geogroup');
                  }).error(function(error) {
                      $scope.status = 'Unable to update geographies : ' + error.message;
                  });
  
                  // console.log($scope.data.geogroup);
              }
  
          };
  
          $scope.getGeographies = function() {
              geoGroupService.getGeographies($scope.data.params).success(function(data) {
  
                  $scope.data.geogroupgeographies = data.geographies;
                  $scope.data.geogroup = data.group;
                  // console.log($scope.data.geographies);
  
                  angular.forEach($scope.data.geogroupgeographies, function(geography, key) {
                      $scope.select(geography.geography_id);
                  });
  
                  // $scope.data.changed = false;
  
              }).error(function(error) {
                  $scope.status = 'Unable to load customer data: ' + error.message;
  
              });
  
              $scope.select = function(id) {
  
                  var found = $filter('filter')($scope.data.geographies, {id: parseInt(id)}, true);
  
                  if (found.length) {
                      // console.log(found);
                      found[0].selected = true;
                      $scope.data.changed = true;
                  }
              };
  
              $scope.deselect = function(id) {
  
                  var found = $filter('filter')($scope.data.geographies, {id: id}, true);
  
                  if (found.length) {
                      found[0].selected = false;
                      $scope.data.changed = true;
                  }
              };
          };
  
  
  
  
  
  
  
  
  
      }]);
  angular.module('MRT')
          .factory('geoGroupService', ['$http', 'env', function($http, env) {
  
          var urlBase = env.apiUrl;
  
          var dataFactory = {
              data: {
                  geogroups: []
              }
          };
  
          dataFactory.getGeoGroupsData = function() {
              return dataFactory.data.geogroups;
          };
  
          dataFactory.list = function(params) {
              return $http.get(urlBase + '/geogroup/', {
                  params: params
              });
          };
  
          dataFactory.getGeographies = function(params) {
              return $http.get(urlBase + '/geogroup/geographies', {
                  params: params
              });
          };
  
          dataFactory.replaceGeographies = function(data) {
              return $http.put(urlBase + '/geogroup/geographies/replace', data);
          };
  
  
  
          return dataFactory;
      }]);
  
  angular.module('MRT').controller('GeoIndicatorCtrl', ['$scope', '$filter', 'ngTableParams', 'geoIndicatorService', function ($scope, $filter, ngTableParams, geoIndicatorService) {
  
      $scope.data = {};
      $scope.data.geoindicators = [];
      $scope.data.response = [];
      var data = [];
  
  
      geoIndicatorService.getGeoIndicatorTotals().success(function (data) {
          $scope.data.geoindicators = data.geoindicators;
  
      }).error(function (error) {
          $scope.status = 'Unable to load customer data: ' + error.message;
      });
  
  
  }]).controller('GeoIndicatorViewCtrl', ['$scope', '$cacheFactory', '$filter', '$stateParams', '$interval', 'ngTableParams', 'geoIndicatorService', 'geoGroupService', function ($scope, $cacheFactory, $filter, $stateParams, $interval, ngTableParams, geoIndicatorService, geoGroupService) {
      $scope.data = {};
      $scope.data.values = [];
      $scope.data.dates = [];
      $scope.data.indicator = {};
      $scope.data.indicators = [];
      $scope.data.selectedIndicator = [];
      $scope.geographies = [];
      $scope.data.selectedGeogroup = '';
      $scope.date = {};
      $scope.date.from = '';
      $scope.date.to = '';
      $scope.summary = {};
      $scope.summary.percentageCompletion = 0;
      $scope.getValue = getValue;
      var countries;
  
      $scope.today = function() {
          $scope.dt = new Date();
      };
      $scope.today();
  
      $scope.clear = function () {
          $scope.dt = null;
      };
  
  
      $scope.disabled = function(date, mode) {
          return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
      };
  
      $scope.toggleMin = function() {
          $scope.minDate = $scope.minDate ? null : new Date();
      };
      $scope.toggleMin();
  
      $scope.openFrom = function($event) {
          $event.preventDefault();
          $event.stopPropagation();
  
          $scope.fromOpened = true;
      };
  
      $scope.openTo = function($event) {
          $event.preventDefault();
          $event.stopPropagation();
  
          $scope.toOpened = true;
      };
  
  
  
      $scope.initDate = new Date('2016-15-20');
      $scope.formats = ['yyyy','dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
      $scope.format = $scope.formats[0];
  
      $scope.datepickerOptions = {
          datepickerMode:"'year'",
          minMode:"'year'",
          maxMode:"'year'",
      //minDate:"minDate",
      showWeeks:"false",
  };
  
  $scope.data.params = {};
  
  $scope.data.playing = false;
  
  var countryTotal = 202;
  
  
  $scope.data.params.id = $stateParams.id;
  $scope.data.params.date;
  $scope.getValues = getValues;
  $scope.selectIndicator = selectIndicator;
  
  /**
  geoGroupService.list($scope.data.params).success(function(data) {
              $scope.data.geogroups = data.geogroups;
          }).error(function(error) {
              $scope.status = 'Unable to load customer data: ' + error.message;
          });**/
  
  
  
  $scope.lineChartData_ = {
      color : [
      'rgba(255, 69, 0, 0.5)',
      'rgba(255, 150, 0, 0.5)',
      'rgba(255, 200, 0, 0.5)',
      'rgba(155, 200, 50, 0.5)',
      'rgba(55, 200, 100, 0.5)'
      ],
      title : {
          text: '商业BI类图表',
          subtext: '纯属虚构'
      },
      tooltip : {
          trigger: 'item',
          formatter: "{a} <br/>{b} : {c}%"
      },
      toolbox: {
          show : true,
          feature : {
              mark : {show: true},
              dataView : {show: true, readOnly: false},
              restore : {show: true},
              saveAsImage : {show: true}
          }
      },
      legend: {
          data : ['展现','点击','访问','咨询','订单']
      },
      series : [
      {
          name:'业务指标',
          type:'gauge',
          center: ['25%','55%'],
              splitNumber: 10,       // 分割段数，默认为5
              axisLine: {            // 坐标轴线
                  lineStyle: {       // 属性lineStyle控制线条样式
                      color: [[0.2, '#228b22'],[0.8, '#48b'],[1, '#ff4500']],
                      width: 8
                  }
              },
              axisTick: {            // 坐标轴小标记
                  splitNumber: 10,   // 每份split细分多少段
                  length :12,        // 属性length控制线长
                  lineStyle: {       // 属性lineStyle控制线条样式
                      color: 'auto'
                  }
              },
              axisLabel: {           // 坐标轴文本标签，详见axis.axisLabel
                  textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                      color: 'auto'
                  }
              },
              splitLine: {           // 分隔线
                  show: true,        // 默认显示，属性show控制显示与否
                  length :30,         // 属性length控制线长
                  lineStyle: {       // 属性lineStyle（详见lineStyle）控制线条样式
                      color: 'auto'
                  }
              },
              pointer : {
                  width : 5
              },
              title : {
                  show : true,
                  offsetCenter: [0, '-40%'],       // x, y，单位px
                  textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                      fontWeight: 'bolder'
                  }
              },
              detail : {
                  formatter:'{value}%',
                  textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                      color: 'auto',
                      fontWeight: 'bolder'
                  }
              },
              data:[{value: 50, name: '完成率'}]
          },
          {
              name:'预期',
              type:'funnel',
              x: '45%',
              width: '45%',
              itemStyle: {
                  normal: {
                      label: {
                          formatter: '{b}预期'
                      },
                      labelLine: {
                          show : false
                      }
                  },
                  emphasis: {
                      label: {
                          position:'inside',
                          formatter: '{b}预期 : {c}%'
                      }
                  }
              },
              data:[
              {value:60, name:'访问'},
              {value:40, name:'咨询'},
              {value:20, name:'订单'},
              {value:80, name:'点击'},
              {value:100, name:'展现'}
              ]
          },
          {
              name:'实际',
              type:'funnel',
              x: '45%',
              width: '45%',
              maxSize: '80%',
              itemStyle: {
                  normal: {
                      borderColor: '#fff',
                      borderWidth: 2,
                      label: {
                          position: 'inside',
                          formatter: '{c}%',
                          textStyle: {
                              color: '#fff'
                          }
                      }
                  },
                  emphasis: {
                      label: {
                          position:'inside',
                          formatter: '{b}实际 : {c}%'
                      }
                  }
              },
              data:[
              {value:30, name:'访问'},
              {value:10, name:'咨询'},
              {value:5, name:'订单'},
              {value:50, name:'点击'},
              {value:80, name:'展现'}
              ]
          }
          ]
      };
  
  
      $scope.lineChartData = {
                  // color: ['rgb(8,48,107)', 'rgb(8,81,156)', 'rgb(66,146,198)', 'rgb(158,202,225)'],
                  color: ['#E09100', '#9BC215', '#00BFF3'],
                  legend: {// legend configuration
                      padding: 0, // The inner padding of the legend, in px, defaults to 5. Can be set as array - [top, right, bottom, left].
                      //itemGap: 10, // The pixel gap between each item in the legend. It is horizontal in a legend with horizontal layout, and vertical in a legend with vertical layout.
                      data: ['Minimum', 'Average', 'Maximum'],
                      textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                          color: '#333',
                          fontFamily: 'Montserrat',
                      }
  
                  },
                  tooltip: {// tooltip configuration
                      trigger: 'axis', // trigger type. Defaults to data trigger. Can also be: 'axis'
                  },
                  textStyle: {
                      fontFamily: 'Montserrat',
                  },
                  toolbox: {
                      show: true,
                      orient: 'vertical',
                      x: 'right',
                      y: 'center',
                      feature: {
                          restore: {
                              show: true,
                              title: 'Restore',
                          },
                          magicType : {
                              show: true,
                              title: {
                                  line: 'Line Chart',
                                  bar: 'Bar Chart',
                                  stack: 'Stack Chart',
                                  tiled: 'Tiled Chart',
                              },
                              type: ['line', 'bar', 'stack', 'tiled']
                          },
                          saveAsImage: {
                              show: true,
                              title: 'Save As Image',
                              type: 'png',
                              lang: ['Language']
                          }
                      }
                  },
                  axisLabel: {           // 坐标轴文本标签，详见axis.axisLabel
  
                  textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                      color: '#333',
                      fontFamily: 'Montserrat',
                  }
              },
                  xAxis: [// The horizontal axis in Cartesian coordinates
                  {
                          type: 'category', // Axis type. xAxis is category axis by default. As for value axis, please refer to the 'yAxis' chapter.
                          data: []
                      }
                      ],
                  yAxis: [// The vertical axis in Cartesian coordinates
                  {
                          type: 'value', // Axis type. yAxis is value axis by default. As for category axis, please refer to the 'xAxis' chapter.
                          //boundaryGap: [0.1, 0.1], // Blank border on each side of the coordinate axis. Value in the array represents percentage.
                          splitNumber: 4                      // Applicable to value axis. The number of segments. Defaults to 5.
                      }
                      ],
                      series: [
                      {
                          name: 'Minimum', // series name
                          type: 'line', // chart type, line, scatter, bar, pie, radar
                          smooth:true,
              itemStyle: {normal: {areaStyle: {type: 'default'}}},
                          data: []
                      },
                      {
                          name: 'Average', // series name
                          type: 'line', // chart type, line, scatter, bar, pie, radar
                          smooth:true,
              itemStyle: {normal: {areaStyle: {type: 'default'}}},
                          // itemStyle: {normal: {areaStyle: {type: 'default'}}},
                          data: []
                      },
                      {
                          name: 'Maximum', // series name
                          type: 'line', // chart type, line, scatter, bar, pie, radar
                          smooth:true,
              itemStyle: {normal: {areaStyle: {type: 'default'}}},
                          data: []
                      }
                      ]
                  };
  
   $scope.completionChartData = {
                  // color: ['rgb(8,48,107)', 'rgb(8,81,156)', 'rgb(66,146,198)', 'rgb(158,202,225)'],
                  color: ['#E09100', '#9BC215', '#00BFF3'],
                  legend: {// legend configuration
                      padding: 0, // The inner padding of the legend, in px, defaults to 5. Can be set as array - [top, right, bottom, left].
                      //itemGap: 10, // The pixel gap between each item in the legend. It is horizontal in a legend with horizontal layout, and vertical in a legend with vertical layout.
                      data: ['Completion'],
                      textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                          color: '#333',
                          fontFamily: 'Montserrat',
                      }
  
                  },
                  tooltip: {// tooltip configuration
                      trigger: 'axis', // trigger type. Defaults to data trigger. Can also be: 'axis'
                  },
                  textStyle: {
                      fontFamily: 'Montserrat',
                  },
                  toolbox: {
                      show: true,
                      orient: 'vertical',
                      x: 'right',
                      y: 'center',
                      feature: {
                          restore: {
                              show: true,
                              title: 'Restore',
                          },
                          saveAsImage: {
                              show: true,
                              title: 'Save As Image',
                              type: 'png',
                              lang: ['Language']
                          }
                      }
                  },
                  axisLabel: {           // 坐标轴文本标签，详见axis.axisLabel
  
                  textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                      color: '#333',
                      fontFamily: 'Montserrat',
                  }
              },
                  xAxis: [// The horizontal axis in Cartesian coordinates
                  {
                          type: 'category', // Axis type. xAxis is category axis by default. As for value axis, please refer to the 'yAxis' chapter.
                          data: []
                      }
                      ],
                  yAxis: [// The vertical axis in Cartesian coordinates
                  {
                          type: 'value', // Axis type. yAxis is value axis by default. As for category axis, please refer to the 'xAxis' chapter.
                          //boundaryGap: [0.1, 0.1], // Blank border on each side of the coordinate axis. Value in the array represents percentage.
                          splitNumber: 4                      // Applicable to value axis. The number of segments. Defaults to 5.
                      }
                      ],
                      series: [
                      {
                          name: 'Completion', // series name
                          type: 'line', // chart type, line, scatter, bar, pie, radar
                          data: [],
                          markPoint : {
                  data : [
                      {type : 'max', name: 'Maximum'},
                      {type : 'min', name: 'Mininum'}
                  ]
              },
              markLine : {
                  data : [
                      {type : 'average', name: 'Average'}
                  ]
              }
                      }
                      ]
                  };
  
                  $scope.chartData = {
                      title: {
                          text: 'World Population (2015)',
                          subtext: 'from United Nations, Total population, both sexes combined, as of 1 July (thousands)',
                          textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                              color: '#333',
                              fontFamily: 'Montserrat',
                          }
                      },
                      nameMap: {
                          'Gambia': 'Gambia, The',
                          'Gambia, The': 'Gambia'
                      },
                      textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                          color: '#333',
                          fontFamily: 'Montserrat',
                      },
                      dataRange: {
                          min: 0,
                          max: 1000000,
                          text: ['High', 'Low'],
                          realtime: false,
                          calculable: true,
                          // color: ['#ffce54', '#00bff3', '#EB5367']
                          color: ['rgb(8,48,107)', 'rgb(8,81,156)', 'rgb(33,113,181)', 'rgb(66,146,198)', 'rgb(107,174,214)', 'rgb(158,202,225)']
                      },
                      series: [
                      {
                          name: 'World Population (2010)',
                          textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                              color: '#333',
                              fontFamily: 'Montserrat',
                          },
                          type: 'map',
                          mapType: 'world',
                          roam: true,
                          mapLocation: {
                              y: 60
                          },
                          itemStyle: {
                              emphasis: {label: {show: true}}
                          },
                          geoCoord: {
                              'Gambia': [-16.56666666, 13.46666666]
                          },
                          data: [
                          {name: 'Afghanistan', value: 28397.812},
                          {name: 'Angola', value: 19549.124},
                          {name: 'Albania', value: 3150.143}
                          ]
                      }
                      ]
                  };
  
  
  
                  $scope.dataCompletionChartData = {
                      tooltip : {
                          formatter: "{b} : {c}%"
                      },
                      toolbox: {
                          show : false,
                          feature : {
                              mark : {show: true},
                              restore : {show: true},
                              saveAsImage : {show: true}
                          }
                      },
                      series : [
                      {
                          name:'Data Completion',
                          textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                              color: '#333',
                              fontFamily: 'Montserrat',
                          },
                          type:'gauge',
                          center : ['50%', '50%'],
                          radius : [0, '75%'],
                          startAngle: 140,
                          endAngle : -140,
                          min: 0,
                          max: 100,
                          precision: 0,
                          splitNumber: 10,
                          axisLine: {
                              show: true,
                              lineStyle: {
                                  // color: [[0.2, 'lightgreen'],[0.4, 'orange'],[0.8, 'skyblue'],[1, '#ff4500']],
                                  color: [[0.2, 'rgb(158,202,225)'],[0.4, 'rgb(66,146,198)'],[0.8, 'rgb(8,81,156)'],[1, 'rgb(8,48,107)']],
                                  // color: ['rgb(8,48,107)', 'rgb(8,81,156)', 'rgb(66,146,198)', 'rgb(158,202,225)'],
                                  width: 30
                              }
                          },
                      axisTick: {            // 坐标轴小标记
                  show: true,        // 属性show控制显示与否，默认不显示
                  splitNumber: 5,    // 每份split细分多少段
                  length :8,         // 属性length控制线长
                  lineStyle: {       // 属性lineStyle控制线条样式
                      color: '#eee',
                      width: 1,
                      type: 'solid'
                  }
              },
              axisLabel: {           // 坐标轴文本标签，详见axis.axisLabel
                  show: true,
                  formatter: function(v){
                      switch (v+''){
                          case '10': return '';
                          case '30': return '';
                          case '60': return '';
                          case '90': return '';
                          default: return '';
                      }
                  },
                  textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                      color: '#333',
                      fontFamily: 'Montserrat',
                  }
              },
              splitLine: {           // 分隔线
                  show: true,        // 默认显示，属性show控制显示与否
                  length :30,         // 属性length控制线长
                  lineStyle: {       // 属性lineStyle（详见lineStyle）控制线条样式
                      color: '#eee',
                      width: 2,
                      type: 'solid'
                  }
              },
              pointer : {
                  length : '80%',
                  width : 8,
                  color : 'auto'
              },
              title : {
                  show : true,
                  offsetCenter: ['-65%', -10],       // x, y，单位px
                  textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                      color: '#333',
                      fontSize : 15
                  }
              },
              detail : {
                  show : true,
                  backgroundColor: 'rgba(0,0,0,0)',
                  borderWidth: 0,
                  borderColor: '#ccc',
                  width: 100,
                  height: 40,
                  offsetCenter: ['-60%', -10],       // x, y，单位px
                  formatter:'{value}%',
                  textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                      color: 'auto',
                      fontSize : 30,
                      fontFamily: 'Montserrat'
                  }
              },
              data:[{value: 50, name: ''}]
          }
          ]
      };
  
      function getDate(d) {
          if(d && typeof d.getFullYear !== 'undefined') {
              return d.getFullYear();
          }
          return d;
      }
  
      function getValues($item, $model) {
          // console.log($model);
          if(typeof $model !== "undefined") {
              // $scope.data.params.date = $model.date;
          }
  
          $scope.data.params.from = getDate($scope.date.from);
          $scope.data.params.to = getDate($scope.date.to);
          $scope.data.params.geogroup = typeof $scope.data.selectedGeogroup.id !== 'undefined' ? $scope.data.selectedGeogroup.id : '';
  
          geoIndicatorService.getGeoIndicatorValues($scope.data.params).success(function (data) {
              $scope.data.values = data[0].values;
              loadGeographies(data[0].values, data[0].dates, data[0].geographies);
              $scope.data.indicator = data[0].indicator;
              $scope.data.dates = data[0].dates;
  
          }).error(function (error) {
              $scope.status = 'Unable to load customer data: ' + error.message;
          });
  
      }
  
      function getValue(geoCode, date, key) {
        var found = $filter('filter')($scope.data.values, {code: geoCode, date: date}, true);
        if(found.length) {
          return Number(found[0][key]);
        }
        return '-';
      }
  
  
      function loadGeographies(values, dates, geographies) {
        var cache = {};
        $scope.geographies = geoIndicatorService.hydrateValues(values, dates, geographies);
        return true;
        for(var i = 0; i < values.length; i++) {
          if(typeof cache[values[i].code] === "undefined") {
            var cp = angular.copy(values[i]);
            cp.values = [];
            var comp = 0;
            var min = 0;
            var max = 0;
            var exist = 0;
            var sum = 0;
            var average = 0;
            var growth = 0;
            for(var ii = 0; ii < dates.length; ii++) {
              var val = getValue(cp.code, dates[ii].date, 'value');
              if(val != '-') {
                // val = parseFloat(val);
                exist++;
                if(val >= max || max == 0) {
                  max = val;
                }
                if(val < min || min === 0) {
                  min = val;
                }
                sum += val;
  
              }
              cp.values.push(val);
            }
            comp = exist > 0 && dates.length > 0  ? (exist/(dates.length))*100 : 0;
            average = exist > 0 && dates.length > 0  ? (sum/(exist)) : 0;
            cp.values.push($filter('number')(comp));
            cp.values.push(min);
            cp.values.push(max);
            cp.values.push(average);
            $scope.geographies.push(cp);
            cache[values[i].code] = true;
          }
        }
      }
  
      var loopIndex = null;
  
      function playGetValues() {
          if($scope.data.playing !== true) {
              return false;
          }
          console.log('plaging');
          // console.log('playGetValues');
          if(loopIndex < 0 || loopIndex === null){
              loopIndex = $scope.data.dates.length-1;
          }
  
  
          if(typeof $scope.data.dates[loopIndex] !== 'undefined') {
              $scope.data.selectedDate = $scope.data.dates[loopIndex];
              $scope.data.params.date = $scope.data.dates[loopIndex].date;
              getValues();
              loopIndex--;
  
          }
  
      }
  
      $scope.startPlay = function() {
          $scope.data.playing = true;
      }
  
      $scope.stopPlay = function() {
          $scope.data.playing =  false;
      }
  
      var play = $interval(playGetValues, 3000);
  
      getAverages();
  
      function selectIndicator($item, $model) {
          if(typeof $model !== "undefined") {
              $scope.data.params.id = $model.id;
          }
  
      }
  
      function reload() {
          getValues();
          getAverages();
          getGeographyAverages();
      }
  
      $scope.reload = reload;
  
      function getAverageSeries(data, min, max) {
          var dates = [];
          var series = {};
          series.average = [];
          series.minimum = [];
          series.maximum = [];
          series.completion = [];
          for(var i = parseInt(min); i <= max; i++) {
              var date = String(i);
              dates.push(date);
              var line = $filter('filter')(data, {date: date}, true);
  
              if(line.length) {
  
                  series.average.push(Number(line[0].average));
                  series.minimum.push(Number(line[0].min));
                  series.maximum.push(Number(line[0].max));
                  series.completion.push(Number(line[0].completion));
              } else {
                  series.average.push('-');
                  series.minimum.push('-');
                  series.maximum.push('-');
                  series.completion.push('-');
              }
          }
  
          $scope.lineChartData.xAxis[0].data = dates;
          $scope.lineChartData.series[0].data = series.minimum;
          $scope.lineChartData.series[1].data = series.average;
          $scope.lineChartData.series[2].data = series.maximum;
          $scope.lineChartData.updatedAt = new Date().toString();
  
  
  
          $scope.completionChartData.xAxis[0].data = dates;
          $scope.completionChartData.series[0].data = series.completion;
          $scope.completionChartData.updatedAt = new Date().toString();
  
          //  console.log(dates);
          // console.log($scope.lineChartData);
      }
  
      $scope.tabSelected = function(type) {
          console.log(type);
          if(type === 'values') {
              $scope.lineChartData.updatedAt = new Date().toString();
          } else if(type === 'completion') {
              $scope.completionChartData.updatedAt = new Date().toString();
          }
      }
  
      function getAverages() {
          geoIndicatorService.getGeoIndicatorAverages($scope.data.params).success(function (data) {
              $scope.data.averages = data.values;
              var min = null;
              var max = null;
              angular.forEach($scope.data.averages, function(value, key) {
                  if(min === null) {
                      min = value.date;
                  }
                  if(max === null) {
                      max = value.date;
                  }
  
                  if(parseInt(max) < parseInt(value.date)) {
                      max = value.date;
                  }
  
                  if(parseInt(min) > parseInt(value.date)) {
                      min = value.date;
                  }
  
              });
  
              console.log("min :" + min + ", max:" + max);
  
              getAverageSeries($scope.data.averages, min, max);
  
          }).error(function (error) {
              $scope.status = 'Unable to load customer data: ' + error.message;
          });
      }
  
      function getGeographyAverages() {
  
           geoIndicatorService.getGeographyGeoIndicatorAverages($scope.data.params).success(function (data) {
              $scope.data.geography_values = data.values;
              $scope.data.geography_completion = data.completion;
              $scope.data.indicator = data.indicator;
              setChartData();
           }).error(function (error) {
              $scope.status = 'Unable to load customer data: ' + error.message;
          });
  
          //
      }
  
      /**
      geoIndicatorService.getGeoIndicatorTotals().success(function (data) {
          $scope.data.indicators = data.geoindicators;
          angular.forEach($scope.data.indicators, function(value, key) {
              if(parseInt(value.id) === parseInt($scope.data.params.id)) {
                  $scope.data.selectedIndicator = value;
              }
          });
  
      }).error(function (error) {
          $scope.status = 'Unable to load customer data: ' + error.message;
      });**/
  
      function setChartData() {
  
          $scope.chartData.title.subtext = $scope.data.indicator.description;
          $scope.chartData.series[0].name = $scope.data.indicator.name;
  
          $scope.chartData.dataRange.min = 0;
          $scope.chartData.dataRange.max = 0;
          $scope.summary = {};
          $scope.summary.percentageCompletion = 0;
  
          var i = 0;
          angular.forEach($scope.data.geography_values, function(value, key) {
              i++;
              value.id = value.code_3;
              value.value = Number(value.average);
              if($scope.chartData.dataRange.min == 0 || value.value < $scope.chartData.dataRange.min) {
                  $scope.chartData.dataRange.min = value.value;
                  $scope.summary.min = value;
              }
  
              if($scope.chartData.dataRange.max == 0 || value.value > $scope.chartData.dataRange.max) {
                  $scope.chartData.dataRange.max = value.value;
                  $scope.summary.max = value;
              }
          });
  
          $scope.summary.percentageCompletion = $scope.data.geography_completion;
  
          $scope.chartData.series[0].data = $scope.data.geography_values;
          // console.log($scope.data.values);
  
          $scope.chartData.title.text = $scope.data.indicator.name;
          updateDataCompletion();
      }
  
      function updateDataCompletion() {
          $scope.dataCompletionChartData.series[0].data[0].value = Number($scope.summary.percentageCompletion);
          $scope.dataCompletionChartData.updatedAt = new Date().toString();
  
      }
  
  
  
      reload();
  
  
  
  }]).controller('GeoIndicatorAddCtrl', ['$scope', '$cacheFactory', '$filter', '$stateParams', '$interval', '$stateParams', 'geographyService', 'geoIndicatorService', function ($scope, $cacheFactory, $filter, $stateParams, $interval, $stateParams, geographyService, geoIndicatorService) {
      var products = [
      {
          "description": "Big Mac",
          "options": [
          {"description": "Big Mac", "image": "//a248.e.akamai.net/assets.github.com/images/icons/emoji/hamburger.png", Pick$: null},
          {"description": "Big Mac & Co", "image": "//a248.e.akamai.net/assets.github.com/images/icons/emoji/hamburger.png", Pick$: null},
          {"description": "McRoyal", "image": "//a248.e.akamai.net/assets.github.com/images/icons/emoji/hamburger.png", Pick$: null},
          {"description": "Hamburger", "image": "//a248.e.akamai.net/assets.github.com/images/icons/emoji/hamburger.png", Pick$: null},
          {"description": "Cheeseburger", "image": "//a248.e.akamai.net/assets.github.com/images/icons/emoji/hamburger.png", Pick$: null},
          {"description": "Double Cheeseburger", "image": "//a248.e.akamai.net/assets.github.com/images/icons/emoji/hamburger.png", Pick$: null}
          ]
      },
                      /**
                      {
                          "description": "Fried Potatoes",
                          "options": [
                              {"description": "Fried Potatoes", "image": "//a248.e.akamai.net/assets.github.com/images/icons/emoji/fries.png", Pick$: null},
                              {"description": "Fried Onions", "image": "//a248.e.akamai.net/assets.github.com/images/icons/emoji/fries.png", Pick$: null}
                          ]
                      }**/
                      ];
                      var countries = [];
                      var firstNames = ["Ted", "John", "Macy", "Rob", "Gwen", "Fiona", "Mario", "Ben", "Kate", "Kevin", "Thomas", "Frank"];
                      var lastNames = ["Tired", "Johnson", "Moore", "Rocket", "Goodman", "Farewell", "Manson", "Bentley", "Kowalski", "Schmidt", "Tucker", "Fancy"];
                      var address = ["Turkey", "Japan", "Michigan", "Russia", "Greece", "France", "USA", "Germany", "Sweden", "Denmark", "Poland", "Belgium"];
  
                      $scope.minSpareRows = 1;
                      $scope.colHeaders = true;
  
                      loadData($stateParams);
  
                      geographyService.getGeographies({}).success(function(data) {
                          countries = data.geographies;
                          var country;
                          for (var i = 0; i < countries.length; i++) {
                              country = countries[i];
                              // $scope.data.push([country.name, '']);
                          }
  
                          // loadData();
  
                      }).error(function(error) {
                          $scope.status = 'Unable to load customer data: ' + error.message;
  
                      });
  
                      function loadData(params) {
                          setDefaultIndicator();
                          if(params && typeof params.id !== 'undefined') {
                              geoIndicatorService.get(params.id).success(function(data) {
                                  $scope.data = data;
  
                              }).error(function(error) {
  
                              });
                          }
                      }
  
                      function setDefaultIndicator() {
                          $scope.data = {
                              name: '',
                              code: '',
                              description: '',
                              series: [['country', '']]
                          };
                      }
  
                      $scope.db = {};
                      $scope.db.items = [];
                      function _loadData() {
                          $scope.db.items = [];
                          for (var i = 0; i < 20; i++) {
                              // countries[i].options = countries;
                              $scope.db.items.push(
                              {
                                  id: i + 1,
                                  name: {
                                      first: firstNames[Math.floor(Math.random() * firstNames.length)],
                                      last: lastNames[Math.floor(Math.random() * lastNames.length)]
                                  },
                                  address: Math.floor(Math.random() * 100000) + ' ' + address[Math.floor(Math.random() * address.length)],
                                  '2010': Math.floor(Math.random() * 100000) / 100,
                                  '2011': Math.floor(Math.random() * 100000) / 100,
                                  '2012': Math.floor(Math.random() * 100000) / 100,
                                  '2013': Math.floor(Math.random() * 100000) / 100,
                                  '2014': Math.floor(Math.random() * 100000) / 100,
                                  isActive: Math.floor(Math.random() * products.length) / 2 == 0 ? 'Yes' : 'No',
                                  country: countries[i]
                              }
                              );
  }
  // $scope.$apply();
  
  }
  
  
  $scope.db.dynamicColumns = [
                     /** {
                          data: 'id',
                          title: 'ID'},
                      {
                          data: 'name.first',
                          title: 'First Name',
                          readOnly: true
                      },
                      {
                          data: 'name.last',
                          title: 'Last Name',
                          readOnly: true
                      },**/
                      // {data: 'address', title: 'Address', width: 150},
                      {data: 'country.name', type: 'autocomplete', title: 'Country', width: 150, source: 'name in countries'},
                      // {data: 'country.name', title: 'Country', },
                      {data: '2010', title:'2010', type: 'numeric', width: 80, format: '$ 0,0.00'},
                      {data: '2011', title:'2011', type: 'numeric', width: 80, format: '$ 0,0.00'},
                      {data: '2012', title:'2012', type: 'numeric', width: 80, format: '$ 0,0.00'},
                      {data: '2013', title:'2013', type: 'numeric', width: 80, format: '$ 0,0.00'},
                      {data: '2014', title:'2014', type: 'numeric', width: 80, format: '$ 0,0.00'},
                      {data: 'isActive', type: 'checkbox', title: 'Is active', checkedTemplate: 'Yes', uncheckedTemplate: 'No', width:65}
                      ];
  
                      $scope.submitForm = function(isValid) {
                          if(isValid) {
                              if(typeof $scope.data.id !== 'undefined' && $scope.data.id) {
                                  geoIndicatorService.update($scope.data).success(function(data) {
                                      $scope.data = data;
  
                                  }).error(function(error) {
                                      $scope.status = 'Unable to save data ' + error.message;
  
                                  });
                              } else {
                                  geoIndicatorService.save($scope.data).success(function(data) {
                                      $scope.data = data;
  
                                  }).error(function(error) {
                                      $scope.status = 'Unable to save data ' + error.message;
  
                                  });
                              }
  
                          }
  
                      }
  
  
  
                  }]);
  
  /**
   *
   *
   */
  angular.module('MRT').directive('indicatorTableDisplay', indicatorTableDisplay);
  
  function indicatorTableDisplay($parse, $filter) {
      var directive = {
          restrict: 'AE',
          templateUrl: 'module/mrt/geoindicator/templates/table-display.html',
          replace: true,
          scope: {data: '=', indicator: '=', dates: '=', toggleSelectColumn: '&', toggleSelectCell: '&'},
          link: function(scope, element, attrs) {
  
            scope.toggleSelectColumn = toggleSelectColumn;
            scope.toggleSelectCell = toggleSelectCell;
  
  
            function toggleSelectCell(labelType, label, geography) {
              var data = $filter('filter')(scope.data, {code: geography.code}, true);
              toggleSelect(labelType, label, data);
            }
  
            function toggleSelectColumn(labelType, label, geoCode) {
              toggleSelect(labelType, label, scope.data);
            }
  
            function toggleSelect(labelType, label, data) {
              var geography;
              var values;
              var value;
              for(var i = 0; i < data.length; i++) {
                geography = data[i];
                values = geography.values;
                for(var ii = 0; ii <values.length; ii++) {
                  var value = values[ii];
                  if(value.selectable === true && value.labelType === labelType && value.label === label) {
                    value.selected = true;
                  } else {
                    value.selected = false;
                  }
                }
              }
            }
            
  
            function selectValue() {
  
            }
  
          }
      };
      return directive;
  }
  ;
  
  /**
   * 
   * 
   */
  angular.module('MRT').directive('indicatorTable', indicatorTable);
  
  function indicatorTable($parse) {
      var directive = {
          restrict: 'AE',
          // templateUrl: 'pension/tpls/term/term-search-pageview.html',
          replace: true,
          //our data source would be an array
          //passed thru chart-data attribute
          scope: {data: '=data'},
          link: function(scope, element, attrs) {
  
              var container = element[0];
    
              var data = function () {
                  // return scope.data;
                  // console.log(scope.data);
                  return scope.data;
                  // return Handsontable.helper.createSpreadsheetData(100, 12);
              };
              
  
              var hot = new Handsontable(container, {
                  data: scope.data,
                  height: 396,
                  colHeaders: true,
                  rowHeaders: true,
                  stretchH: 'all',
                  columnSorting: false,
                  contextMenu: true,
                  minSpareRows: 1
                  // fixedRowsTop: 1
              });
  
              scope.$watch('data', function() { 
                  console.log('changed');
                  // hot.render();
                  console.log(scope.data);
                  hot.loadData(scope.data);
              });
  
          }
      };
      return directive;
  }
  ;
  
  angular.module('MRT')
  .factory('geoIndicatorService', ['$http', '$filter', 'env', 'localStorageService', 'CacheFactory', function($http, $filter, env, localStorageService, CacheFactory) {
  
  
  	var urlBase = env.apiUrl;
  	var dataFactory = {};
  
  	if (!CacheFactory.get('geoIndicatorsCache')) {
        // or CacheFactory('bookCache', { ... });
        CacheFactory.createCache('geoIndicatorsCache', {
          deleteOnExpire: 'aggressive',
          recycleFreq: 60 * 60 * 1000,
          storageMode: 'localStorage'
        });
      }
  
      if (!CacheFactory.get('geoIndicatorTotalCache')) {
        CacheFactory.createCache('geoIndicatorTotalCache', {
          deleteOnExpire: 'aggressive',
          recycleFreq: 60 * 60 * 1000,
          storageMode: 'localStorage'
        });
      }
  
  
  	var geoIndicatorsCache = CacheFactory.get('geoIndicatorsCache');
  	var geoIndicatorTotalCache = CacheFactory.get('geoIndicatorTotalCache');
  
  	dataFactory.getGeoIndicators = function(params) {
  		return $http.get(urlBase + '/geoindicator/', {
  			// params: params,
  			// cache: geoIndicatorsCache
  		});
  	};
  
  
  	dataFactory.getGeoIndicatorAverages= function(params) {
  		return $http.get(urlBase + '/geoindicator/average/', {
  			params: params,
  			cache: true
  		});
  	};
  
  	dataFactory.getGeographyGeoIndicatorAverages= function(params) {
  		return $http.get(urlBase + '/geoindicator/geography/average/', {
  			params: params,
  			cache: true
  		});
  	};
  
  
  	dataFactory.getGeoIndicatorTotals = function(params) {
  		return $http.get(urlBase + '/geoindicator/total/', {
  			params: params,
  			// cache: geoIndicatorTotalCache
  		});
  	};
  
  	dataFactory.getGeoIndicatorValues = function(params) {
  		return $http.get(urlBase + '/geoindicator/values', {
  			params: params,
  			cache: true
  		});
  	};
  
  	dataFactory.get = function(id) {
  		return $http.get(urlBase + '/geoindicator/' + id + '/show', {});
  	};
  
  	dataFactory.save = function(data) {
  		return $http.post(urlBase + '/geoindicator/create', data);
  	};
  
  	dataFactory.update = function(data) {
  		return $http.post(urlBase + '/geoindicator/update', data);
  	};
  
  	dataFactory.getGeoIndicatorsFromCache = function(params) {
  		var key = 'geo_indicator_list';
  		var $return = localStorageService.get(key);
  		if (typeof $return !== "undefined" && $return.length)  {
  			return $return;
  		} else {
  			dataFactory.getGeoIndicators(params).success(function(data) {
  				localStorageService.set(key, data);
  				return data;
  
  			}).error(function(error) {
  				status = 'Unable to load customer data: ' + error.message;
  
  			});
  		}
  	};
  
  	dataFactory.hydrateValues = hydrateValues;
  	dataFactory.getSummary = getSummary;
  
  	function getValue(values, geoCode, date, key) {
  		var found = $filter('filter')(values, {code: geoCode, date: date}, true);
  		if(found.length) {
  			return Number(found[0][key]);
  		}
  		return '-';
  	}
  
  
  	function hydrateValues(values, dates, countries) {
  		var cache = {};
  		$return = [];
  		for(var i = 0; i < countries.length; i++) {
  			if(typeof cache[countries[i].code] === "undefined") {
  				var cp = angular.copy(countries[i]);
  				cp.values = [];
  				var comp = 0;
  				var min = 0;
  				var max = 0;
  				var exist = 0;
  				var sum = 0;
  				var average = 0;
  				var growth = 0;
  				for(var ii = 0; ii < dates.length; ii++) {
  					var val = getValue(values, cp.code, dates[ii].date, 'value');
  					if(val != '-') {
  						// val = parseFloat(val);
  						exist++;
  						if(val >= max || max == 0) {
  							max = val;
  						}
  						if(val < min || min === 0) {
  							min = val;
  						}
  						sum += val;
  
  					}
  					append(cp.values, val, 'date', dates[ii].date);
  				}
  				comp = exist > 0 && dates.length > 0  ? (exist/(dates.length))*100 : 0;
  				average = exist > 0 && dates.length > 0  ? (sum/(exist)) : '-';
  				min = exist > 0 && dates.length > 0  ? min : '-';
  				max = exist > 0 && dates.length > 0  ? max : '-';
  				append(cp.values, comp, 'derived', 'completion', false);
  				append(cp.values, min, 'derived', 'minimum');
  				append(cp.values, max, 'derived', 'maximum');
  				append(cp.values, average, 'derived', 'average');
  				$return.push(cp);
  				cache[countries[i].code] = true;
  			}
  		}
  		return $return;
  	}
  
  	function append(arr, value, labelType, label, selectable) {
  		var item = {value : value};
  		item.labelType = labelType;
  		item.label = label;
  		item.type = value === '-' ? 'na' : 'number';
  		item.selectable = value === '-' ? false : true;
  
  		if(typeof selectable !== "undefined") {
  			item.selectable = selectable;
  		}
  		if(typeof item.selected === 'undefined' && label === 'average') {
  			item.selected = true;
  		}
  		arr.push(item);
  	}
  
  	function getSummary(data) {
  		var summary = {};
  		var completion = 0;
  		for(var i = 0; i < data.length; i++) {
  			completion += getIndicatorValue(data[i].values, 'completion');
  		}
  		summary.completion = completion !== 0 && data.length > 0 ? (completion/data.length) : 0;
  		return summary;
  	}
  
  	function getIndicatorValue(values, label) {
  		var value = 0;
  		for(var i = 0; i < values.length; i++) {
  			if(values[i].label === label) {
  				value = values[i].value;
  			}
  		}
  		return value;
  	}
  
  
  	return dataFactory;
  }]);
  
  angular.module('MRT').controller('GeoIndicatorGroupCtrl', ['$scope', '$filter', 'geoIndicatorGroupService', function($scope, $filter, geoIndicatorGroupService) {
  
  		$scope.data = {};
  		$scope.search = '';
  		$scope.data.geoindicatorgroups = [];
  
  		geoIndicatorGroupService.list($scope.data.params).success(function(data) {
  
  			$scope.data.geoindicatorgroups = data.groups;
  
  		}).error(function(error) {
  			$scope.status = 'Unable to load customer data: ' + error.message;
  
  		});
  
  
  	}]).controller('GeoIndicatorGroupViewCtrl', ['$scope', '$filter', '$state', '$stateParams', 'geoIndicatorGroupService', 'geoIndicatorService', function($scope, $filter, $state, $stateParams, geoIndicatorGroupService, geoIndicatorService) {
  		$scope.data = {};
  		$scope.templateVar = {};
  
  		$scope.data.changed = false;
  		$scope.data.list = [];
  		$scope.data.selectedList = [];
  		$scope.data.group = {name: '', description: ''};
  		$scope.data.params = {};
  		$scope.data.params.id = $stateParams.id;
  
  		geoIndicatorService.getGeoIndicators($scope.data.params).success(function(data) {
  			$scope.data.list = data.geoindicators;
  			$scope.sortList();
  			$scope.getIndicators();
  
  		}).error(function(error) {
  			$scope.status = 'Unable to load customer data: ' + error.message;
  
  		});
  
  		$scope.sortList = function() {
  			$scope.data.list = $filter('orderBy')($scope.data.list, 'name');
  		};
  
  
  		$scope.changed = function() {
  			$scope.data.changed = true;
  		};
  
  		// function to submit the form after all validation has occurred			
  		$scope.submitForm = function(isValid) {
  
  			// check to make sure the form is completely valid
  			if (isValid) {
  				// alert('our form is amazing');
  				$scope.data.group.indicators = [];
  				angular.forEach($scope.data.list, function(item, key) {
  					if (!angular.isUndefined(item.selected) && item.selected === true) {
  						$scope.data.group.indicators.push(item);
  					}
  				});
  
  				geoIndicatorGroupService.replace($scope.data.group).success(function(data) {
  					$state.go('geoindicatorgroup');
  					console.log($scope.data.group);
  				}).error(function(error) {
  					$scope.status = 'Unable to update indicators : ' + error.message;
  				});
  
  				// console.log($scope.data.geogroup);
  			}
  
  		};
  
  		$scope.getIndicators = function() {
  			geoIndicatorGroupService.getIndicators($scope.data.params).success(function(data) {
  
  				$scope.data.selectedList = data.indicators;
  				$scope.data.group = data.group;
  
  				angular.forEach($scope.data.selectedList, function(item, key) {
  					$scope.select(item.geoindicator_id);
  				});
  
  				// $scope.data.changed = false;
  
  			}).error(function(error) {
  				$scope.status = 'Unable to load customer data: ' + error.message;
  
  			});
  
  		};
  
  		$scope.select = function(id) {
  
  			var found = $filter('filter')($scope.data.list, {id: id}, true);
  			// console.log($scope.data.list);
  			if (found.length) {
  				// console.log('selected' + id);
  				// console.log(found);
  				found[0].selected = true;
  				$scope.data.changed = true;
  			}
  		};
  
  		$scope.deselect = function(id) {
  
  			var found = $filter('filter')($scope.data.list, {id: id}, true);
  
  			if (found.length) {
  				found[0].selected = false;
  				$scope.data.changed = true;
  			}
  		};
  
  
  
  
  
  
  
  
  	}]);
  angular.module('MRT')
          .factory('geoIndicatorGroupService', ['$http', 'env', function($http, env) {
  
          var urlBase = env.apiUrl;
  
          var dataFactory = {
              data: {
                  geoindicatorgroups: []
              }
          };
  
  
          dataFactory.list = function(params) {
              return $http.get(urlBase + '/geoindicatorgroup/', {
                  params: params
              });
          };
  
          dataFactory.getIndicators = function(params) {
              return $http.get(urlBase + '/geoindicatorgroup/indicators', {
                  params: params
              });
          };
          
          dataFactory.replace = function(data) {
              return $http.put(urlBase + '/geoindicatorgroup/indicators/replace', data);
          };
  
  
  
          return dataFactory;
      }]);
  angular.module('MRT').controller('GeoModelAddAdvanceCtrl', ['$scope', '$filter', '$stateParams', '$modal', '$log', 'geoModelService', 'geoGroupService', function($scope, $filter, $stateParams, $modal, $log, geoModelService, geoGroupService) {
  
  
  }]);
  
  angular.module('MRT').controller('GeoModelWeightCtrl', ['$scope', '$filter', '$stateParams', '$modal', '$log', 'geoModelService', 'geoGroupService', function($scope, $filter, $stateParams, $modal, $log, geoModelService, geoGroupService) {
  		$scope.data = {weight: 10};
  		$scope.response = {};
  		$scope.response.geogroups = {data: []};
  		$scope.response.geoindicators = {list: []};
  		$scope.response.parameters = {};
  		$scope.data.values = {};
  		$scope.data.maxGeoScore = 0;
  		$scope.data.scoreMax = 100;
  		$scope.data.indicators = [];
  		$scope.data.clusters = [];
  		$scope.data.clusterData = [];
  		$scope.data.params = {id: $stateParams.id, date: 2013};
  		$scope.predicate = '-xScore';
  		$scope.data.selectedParameterId = '';
  		$scope.data.list = [];
  		$scope.data.selectedParameter = {};
  
  		$scope.clusterio = new clusterio.KMeans();
  
  		$scope.data.dates = [];
  
  		for (i = 2014; i >= 2000; i--) {
  			$scope.data.dates.push(i);
  		}
  
  		$scope.data.params.date = $scope.data.dates[0];
  		// Here we are referencing the same object, so Angular inits the select box correctly
  
  		$scope.getIndicatorValues = function(model, item) {
  			$scope.data.params.geogroup_id = item.id;
  			$scope.getValues();
  		};
  
  		$scope.getClusterIndicatorValues = function(model, item) {
  			$scope.data.params.geogroup_id = item.id;
  			$scope.getValues();
  		};
  
  		$scope.setClusterData = function() {
  			$scope.data.clusterData = [];
  			angular.forEach($scope.data.values.geographies, function(geography, key) {
  				var row = [];
  				angular.forEach($scope.response.geoindicators.list, function(indicator, key) {
  					var geographyIngicator = $scope.getGeographyIndicator(geography, indicator);
  					if (typeof geographyIngicator.value !== "undefined") {
  						row.push(geographyIngicator.value);
  					} else {
  						row.push(null);
  					}
  				});
  				$scope.data.clusterData.push(row);
  			});
  
  			// $scope.cluster();
  			// console.log($scope.data.clusterData);
  		};
  
  		$scope.cluster = function() {
  			$scope.data.clusters = $scope.clusterio.cluster($scope.data.clusterData, 9);
  			// console.log($scope.data.clusters);
  		};
  
  
  		$scope.getValues = function() {
  			geoModelService.getValues($scope.data.params).success(function(data) {
  
  				$scope.data.values = data;
  				$scope.setIndicators();
  				$scope.setMinMaxValues();
  				$scope.updateScores();
  				// $scope.setClusterData();
  
  
  			}).error(function(error) {
  				$scope.status = 'Unable to load customer data: ' + error.message;
  
  			});
  		};
  
  		$scope.getParameterByAxis = function(axis) {
  			if (typeof axis !== "undefined") {
  
  				var parameter = $filter('filter')($scope.response.parameters, {axis: axis}, true);
  				if (parameter.length) {
  					return parameter[0];
  
  				}
  
  			}
  			return {};
  		};
  
  		$scope.setSelectedParameter = function(id) {
  			if (typeof id !== "undefined") {
  				id = id.toString();
  				$scope.data.selectedParameterId = id;
  				var parameter = $filter('filter')($scope.response.parameters, {id: id}, true);
  				if (parameter.length) {
  					$scope.data.selectedParameter = parameter[0];
  					return $scope.data.selectedParameter;
  				}
  
  			}
  			return null;
  		};
  
  
  		$scope.selectParameters = function(id) {
  
  			if ($scope.setSelectedParameter(id) !== null) {
  				$scope.predicate = '-' + $scope.getParameterAxis(id) + 'Score';
  				//$scope.predicate = '-xScore';
  				// $scope.data.selectedParameter =
  				angular.forEach($scope.response.geoindicators.list, function(indicator, key) {
  					if (indicator.parameter_id === id) {
  						indicator.selected = true;
  					} else {
  						indicator.selected = false;
  					}
  				});
  			}
  			;
  			$scope.updateScores();
  		};
  
  		// get indicators
  		geoModelService.getIndicators($scope.data.params).success(function(data) {
  
  			$scope.response.geoindicators.list = data.indicators;
  			$scope.response.parameters = data.parameters;
  			angular.forEach($scope.response.parameters, function(parameter, key) {
  				parameter.id = parameter.id.toString();
  			});
  
  			$scope.selectParameters($scope.response.parameters[0].id);
  			$scope.setIndicators();
  
  
  		}).error(function(error) {
  			$scope.status = 'Unable to load customer data: ' + error.message;
  
  		});
  
  		geoGroupService.list().success(function(data) {
  			$scope.response.geogroups.data = data.geogroups;
  
  
  		}).error(function(error) {
  			$scope.status = 'Unable to load groups data: ' + error.message;
  
  		});
  
  		$scope.setIndicators = function() {
  			$scope.indicatorChanged();
  			// $scope.data.indicators = $scope.data.values.indicators;
  			angular.forEach($scope.response.geoindicators.list, function(indicator, key) {
  				indicator.max = 0;
  				indicator.maxScore = 0;
  			});
  		};
  
  		$scope.setMinMaxValues = function() {
  			// $scope.data.indicators = $scope.data.values.indicators;
  			angular.forEach($scope.response.geoindicators.list, function(indicator, key) {
  				indicator.minimumValue = null;
  				indicator.maximumValue = null;
  				// set minimum and maximum values
  				angular.forEach($scope.data.values.geographies, function(geography, key) {
  					var geographyIndicator = $scope.getGeographyIndicator(geography, indicator);
  					if (typeof geographyIndicator.value !== "undefined") {
  						if (indicator.minimumValue === null || geographyIndicator.value < indicator.minimumValue) {
  							indicator.minimumValue = geographyIndicator.value;
  						}
  						if (indicator.maximumValue === null || geographyIndicator.value > indicator.maximumValue) {
  							indicator.maximumValue = geographyIndicator.value;
  						}
  
  					}
  				});
  			});
  		};
  
  
  		$scope.indicatorChanged = function(indicator) {
  			$scope.data.maxGeoScore = 0;
  			if (typeof indicator !== "undefined") {
  				indicator.max = 0;
  				indicator.maxScore = 0;
  			}
  			// alert("hey");
  		};
  
  
  		$scope.toggleRelevanceSort = function(indicator) {
  			indicator.relevance_sort = indicator.relevance_sort === 'ASC' ? 'DESC' : 'ASC';
  			$scope.updateScores();
  		};
  
  		$scope.getRelevanceSortDescription = function(indicator) {
  			return indicator.relevance_sort === 'ASC' ? 'Low To High' : 'High To Low';
  		};
  
  
  
  		$scope.getParameterAxis = function(id) {
  			if (typeof id !== "undefined") {
  				id = id.toString();
  				var parameter = $filter('filter')($scope.response.parameters, {id: id}, true);
  				if (parameter.length) {
  					// console.log(parameter[0].axis.toLowerCase());
  					return parameter[0].axis.toLowerCase();
  
  				}
  			}
  			return '';
  		};
  
  
  		$scope.geGeoSelectedParameterScore = function(geography) {
  			var key = $scope.getParameterAxis($scope.data.selectedParameterId) + 'Score';
  			return geography[key];
  		};
  
  		$scope.geGeoParameterScore = function() {
  
  		};
  
  		$scope.getTotalIndicatorWeight = function(parameter_id) {
  			var indicators = $filter('filter')($scope.response.geoindicators.list, {parameter_id: parameter_id}, true);
  			var $return = 0;
  			angular.forEach(indicators, function(indicator, key) {
  				$return += indicator.weight;
  			});
  			return $return;
  		};
  
  		$scope.updateScores = function() {
  			var x = 3;
  			var y = 3;
  			// $scope.app.unsavedChanges = true;
  			angular.forEach($scope.response.parameters, function(parameter, key) {
  				parameter.maxScore = 0;
  				parameter.minScore = 0;
  				var axis = $scope.getParameterAxis(parameter.id);
  				var factor = (axis === 'x') ? x : y;
  				var maxScore = 0;
  				var totalIndicatorWeight = $scope.getTotalIndicatorWeight(parameter.id);
  
  				angular.forEach($scope.data.values.geographies, function(geography, key) {
  					var score = $scope.calculateGeographyScore(geography, parameter.id, totalIndicatorWeight);
  
  					if (score < parameter.minScore) {
  						parameter.minScore = score;
  					}
  					if (score > parameter.maxScore) {
  						parameter.maxScore = score;
  					}
  
  					if (score > maxScore) {
  						maxScore = score;
  					}
  				});
  
  				// console.log("max score : " + maxScore);
  
  				angular.forEach($scope.data.values.geographies, function(geography, key) {
  
  					var axisKey = axis + 'Axis';
  					var scoreKey = axis + 'Score';
  					var boundry = maxScore / factor;
  					for (i = 1; i <= factor; i++) {
  						var topBoundary = (boundry * i);
  						if (i === factor) {
  							topBoundary = maxScore;
  						}
  						if (geography[scoreKey] <= topBoundary && geography[scoreKey] >= (boundry * (i - 1))) {
  							geography[axisKey] = i;
  							// break;
  						}
  					}
  
  				});
  			});
  			// console.log($scope.data.values.geographies);
  			// console.log($scope.response.parameters);
  		};
  
  		$scope.calculateGeographyScore = function(geography, parameter_id, totalIndicatorWeight) {
  
  			var $return = 0;
  			var indicators = $filter('filter')($scope.response.geoindicators.list, {parameter_id: parameter_id}, true);
  			var per = totalIndicatorWeight;
  			var parameterAxis = $scope.getParameterAxis(parameter_id);
  			var scoreKey = parameterAxis + 'Score';
  			angular.forEach(indicators, function(indicator, key) {
  				var found = $filter('filter')(geography.indicators, {geography_id: geography.id, geoindicator_id: indicator.id}, true);
  				// console.log(indicator);
  				if (found.length) {
  					var weight = ((indicator.weight / per) * 100);
  					// $return = indicator.weight;
  					// found[0].score = (($scope.data.scoreMax / found[0].value) * weight);
  					if (indicator.relevance_sort === 'ASC') {
  						found[0][scoreKey] = ((indicator.minimumValue / found[0].value) * weight);
  					} else {
  						found[0][scoreKey] = ((found[0].value / indicator.maximumValue) * weight);
  					}
  
  					if (found[0][scoreKey] > indicator.maxScore) {
  						indicator.max = found[0][scoreKey];
  						indicator.maxScore = found[0][scoreKey];
  					}
  					$return += found[0][scoreKey];
  				}
  			});
  
  
  			geography[scoreKey] = $return;
  			return $return;
  		};
  
  		$scope.getScore = function(geography, parameter_id) {
  			return 0;
  			if (typeof parameter_id === "undefined") {
  				parameter_id = $scope.data.selectedParameterId;
  			}
  			var $return = 0;
  			var per = $scope.response.geoindicators.list.length * this.data.values.settings.max_weight;
  			angular.forEach($scope.response.geoindicators.list, function(indicator, key) {
  				if (indicator.selected === true) {
  					var found = $filter('filter')(geography.indicators, {geography_id: geography.id, geoindicator_id: indicator.id}, true);
  					// console.log(indicator);
  					if (found.length) {
  						var weight = ((indicator.weight / per) * 100);
  						// $return = indicator.weight;
  						// found[0].score = (($scope.data.scoreMax / found[0].value) * weight);
  						if (indicator.relevance_sort === 'ASC') {
  							found[0].score = ((indicator.minimumValue / found[0].value) * weight);
  						} else {
  							found[0].score = ((found[0].value / indicator.maximumValue) * weight);
  						}
  
  						if (found[0].score > indicator.maxScore) {
  							indicator.max = found[0].value;
  							indicator.maxScore = found[0].score;
  						}
  						$return += found[0].score;
  					}
  				}
  			});
  
  
  			geography.score = $return;
  			if (geography.score > $scope.data.maxGeoScore) {
  				$scope.data.maxGeoScore = geography.score;
  			}
  
  			return $return;
  		};
  
  		$scope.getGeographyIndicator = function(geography, indicator) {
  			var found = $filter('filter')(geography.indicators, {geography_id: geography.id, geoindicator_id: indicator.id}, true);
  
  			if (found.length) {
  				return found[0];
  			} else {
  				return {};
  			}
  		};
  
  		$scope.getSelectedScore = function(i) {
  			var axis = $scope.getParameterAxis(i.parameter_id);
  			if (axis !== null) {
  				return (typeof i[axis + 'Score']) !== "undefined" ? i[axis + 'Score'] : 0;
  			}
  			return 0;
  		};
  
  		$scope.getSelectedGeographyIndicator = function(geography, indicator) {
  			// add parameter id selector
  			var found = $filter('filter')(geography.indicators, {geography_id: geography.id, geoindicator_id: indicator.id, parameter_id: $scope.data.selectedParameterId}, true);
  
  			if (found.length) {
  				return found[0];
  			} else {
  				return {};
  			}
  		};
  
  
  
  		$scope.open = function(size) {
  			var modalInstance = $modal.open({
  				templateUrl: 'module/mrt/geomodel/templates/replace.html',
  				controller: 'GeoModelIndicatorUpdateCtrl',
  				size: size,
  				resolve: {
  					geoindicators: function() {
  						return $scope.response.geoindicators.list;
  					},
  					selectedParameter: function() {
  						return $scope.data.selectedParameter;
  					},
  					params: function() {
  						return $scope.data.params;
  					}
  				}
  			});
  
  			modalInstance.result.then(function(selectedItem) {
  				$scope.selected = selectedItem;
  			}, function() {
  				// $log.info('Modal dismissed at: ' + new Date());
  			});
  		};
  
  
  	}]).controller('GeoModelCtrl', ['$scope', '$filter', '$modal', 'geoModelService', 'geoGroupService', function($scope, $filter, $modal, geoModelService, geoGroupService) {
  		$scope.data = {};
  
  		$scope.load = function() {
  
  			geoModelService.list($scope.data.params).success(function(data) {
  				$scope.data.geomodels = data.geomodels;
  			}).error(function(error) {
  				$scope.status = 'Unable to load customer data: ' + error.message;
  
  			});
  		};
  
  		$scope.load();
  
  		$scope.open = function(size) {
  			var modalInstance = $modal.open({
  				templateUrl: 'module/mrt/geomodel/templates/replace.html',
  				controller: 'GeoModelIndicatorUpdateCtrl',
  				size: size,
  				resolve: {
  					geoindicators: function() {
  						return {};
  					},
  					selectedParameter: function() {
  						return {};
  					},
  					params: function() {
  						return {};
  					}
  				}
  			});
  
  			modalInstance.result.then(function(selectedItem) {
  				// $scope.selected = selectedItem;
  				console.log('here');
  				$scope.load();
  			}, function() {
  				// $log.info('Modal dismissed at: ' + new Date());
  			});
  		};
  
  	}]).controller('GeoModelIndicatorUpdateCtrl', ['$scope', '$filter', '$modalInstance', '$state', 'geoindicators', 'params', 'geoIndicatorGroupService', 'geoIndicatorService', 'geoModelService', function($scope, $filter, $modalInstance, $state, geoindicators, params, geoIndicatorGroupService, geoIndicatorService, geoModelService) {
  		$scope.data = {};
  		$scope.data.params = params;
  
  		$scope.data.indicators = {};
  		$scope.data.parameter = {};
  		$scope.data.model = {};
  
  		geoModelService.new($scope.data.params).success(function(data) {
  			$scope.data.model = data;
  			$scope.selectIndicators();
  			// console.log($scope.data.params);
  			// console.log($scope.data.model);
  
  		}).error(function(error) {
  			$scope.status = 'Unable to load customer data: ' + error.message;
  
  		});
  
  		// console.log($scope.data.geoindicators);
  
  		$scope.ok = function() {
  			$modalInstance.close($scope.data.geoindicators);
  		};
  
  		$scope.cancel = function() {
  			$modalInstance.dismiss('cancel');
  			console.log($scope.data.geoindicators);
  		};
  
  		geoIndicatorService.getGeoIndicators(params).success(function(data) {
  			$scope.data.list = data.geoindicators;
  			$scope.sortList();
  			$scope.selectIndicators();
  
  		}).error(function(error) {
  			$scope.status = 'Unable to load customer data: ' + error.message;
  			// console.log($scope);
  		});
  
  
  		$scope.selectIndicators = function() {
  			if (!angular.isUndefined($scope.data.model.parameters) && !angular.isArray($scope.data.model.parameters)) {
  				angular.forEach($scope.data.model.parameters, function(parameter, key) {
  					angular.forEach(parameter.indicators, function(indicator, key) {
  						$scope.select(indicator.geoindicator_id, indicator.parameter_id);
  					});
  				});
  			}
  		};
  
  		$scope.filterSelected = function(parameter_id, reverse)
  		{
  			return function(indicator) {
  				var $return = false;
  				if (typeof reverse === 'undefinded') {
  					reverse = false;
  				}
  				if (angular.isUndefined(indicator.selected) || !angular.isArray(indicator.selected)) {
  					indicator.selected = [];
  					return false;
  				}
  				if (indicator.selected.indexOf(parameter_id) !== -1)
  				{
  					$return = true;
  				}
  
  				return reverse === true ? !$return : $return;
  				// return false;
  			};
  		};
  
  		$scope.select = function(id, parameter_id) {
  			var found = $filter('filter')($scope.data.list, {id: id}, true);
  			if (angular.isArray(found) && found.length) {
  				if (angular.isUndefined(found[0].selected) || !angular.isArray(found[0].selected)) {
  					found[0].selected = [];
  				}
  				if (found[0].selected.indexOf(parameter_id) === -1) {
  					found[0].selected.push(parameter_id);
  				}
  				// console.log(found[0].selected);
  			}
  		};
  
  
  		$scope.deselect = function(id, parameter_id) {
  			var found = $filter('filter')($scope.data.list, {id: id}, true);
  			if (found.length) {
  				if (angular.isUndefined(found[0].selected) || !angular.isArray(found[0].selected)) {
  					found[0].selected = [];
  				}
  				for (var i = found[0].selected.length - 1; i >= 0; i--) {
  					if (found[0].selected[i] === parameter_id) {
  						found[0].selected.splice(i, 1);
  						// break;       //<-- Uncomment  if only the first term has to be removed
  					}
  				}
  			}
  
  		};
  
  		$scope.sortList = function() {
  			$scope.data.list = $filter('orderBy')($scope.data.list, 'name');
  		};
  
  		$scope.changed = function() {
  			$scope.data.changed = true;
  		};
  
  		// function to submit the form after all validation has occurred
  		$scope.submitForm = function(isValid) {
  			if (isValid) {
  
  				$scope.data.modelParameterIndicators = [];
  				var model = $scope.master = angular.copy($scope.data.model);
  				angular.forEach(model.parameters, function(parameter, key) {
  					var parameter_id = angular.copy(parameter.id);
  					parameter.indicators = [];
  					angular.forEach($scope.data.list, function(item, key) {
  						if (!angular.isUndefined(item.selected) && item.selected.indexOf(parameter_id) !== -1) {
  							parameter.indicators.push({id: item.id});
  						}
  					});
  				});
  
  				geoModelService.replace(model).success(function(data) {
  					$state.go('geomodel');
  					// console.log($scope.data.group);
  					$modalInstance.close();
  				}).error(function(error) {
  					$scope.status = 'Unable to update indicators : ' + error.message;
  				});
  
  				console.log(model);
  				return false;
  
  				// console.log($scope.data.geogroup);
  			}
  		};
  
  	}]);
  
  angular.module('MRT').directive('geoModelCluster', geoModelCluster);
  function geoModelCluster() {
      var directive = {
          restrict: 'AE',
          replace: true,
          templateUrl: 'js/module/mrt/geomodel/templates/geomodel-cluster.html',
          link: function(scope, element, attrs) {
              // alert("hey");
          }
      };
      return directive;
  };
  angular.module('MRT').directive('geoModelGeMatrix', GeoModelGeMatrix);
  function GeoModelGeMatrix() {
      var directive = {
          restrict: 'AE',
          replace: true,
          templateUrl: 'js/module/mrt/geomodel/templates/geomodel-ge-matrix.html'
      };
      return directive;
  }
  ;
  angular.module('MRT').directive('geoModelMap', GeoModelMap);
  function GeoModelMap() {
      var directive = {
          restrict: 'AE',
          replace: true,
          templateUrl: 'js/module/mrt/geomodel/templates/geomodel-map.html'
      };
      return directive;
  }
  ;
  angular.module('MRT').directive('geoModelTable', geoModelTable);
  function geoModelTable() {
      var directive = {
          restrict: 'AE',
          replace: true,
          templateUrl: 'js/module/mrt/geomodel/templates/geomodel-table.html'
      };
      return directive;
  }
  ;
  angular.module('MRT').directive('geoModelWeight', geoModelWeight);
  function geoModelWeight() {
      var directive = {
          restrict: 'AE',
          replace: true,
          templateUrl: 'js/module/mrt/geomodel/templates/geomodel-weight.html',
          link: function(scope, element, attrs) {
              // alert("hey");
          }
      };
      return directive;
  }
  ;
  angular.module('MRT')
          .factory('geoModelService', ['$http', 'env', 'localStorageService', function($http, env, localStorageService) {
  
  
          var urlBase = env.apiUrl;
          var dataFactory = {};
          var cacheKey = 'model_creation';
          var modelTypes = [
            {
              id: 'ge-mckinsey',
              name: 'GE MCKinsey Matrix',
              image: 'img/matrix.png',
              description: "The GE matrix / McKinsey matrix (MKM) is a model to perform a business portfolio analysis on the Strategic Business Units of a corporation. A business portfolio is the collection of Strategic Business Units that make up a corporation.",
              dimensions: [
                {id: 'c-specifics', name: 'Country Specifics', selection: 'single', weighted: true},
                {id: 'm-attractiveness', name: 'Market Attractiveness', selection: 'single', weighted: true}
              ]
            },
            {
              id: '3-dimentional-bubble',
              name: '3 Dimentional Bubble',
              image: 'img/bubble.png',
              description: "A motion chart is a dynamic bubble chart which allows efficient and interactive exploration and visualization of longitudinal multivariate Data.",
              dimensions: [
                {id: 'x-axis', name: 'X-Axis', selection: 'range'},
                {id: 'y-axis', name: 'Y-Axis', selection: 'range'},
                {id: 'bubble-size', name: 'Bubble Size', selection: 'range'}
              ]
            },
            {
              id: 'map',
              name: 'map',
              image: 'img/map.png',
              description: "Map",
              dimensions: [
                {id: 'indicator', name: 'Indicators', selection: 'range', weighted: true}
              ]
            },
            {
              id: 'weighted-table',
              name: 'Weighted Table',
              image: 'img/charts/graph-5.png',
              description: "Weighted table description",
              dimensions: [
                {id: 'headers', name: 'Headers', selection: 'range', weighted: true},
              ]
            },
            {
              id: 'stack-chart',
              name: 'Stack Chart',
              image: 'img/charts/graph-24.png',
              description: "Stack chart description",
              dimensions: [
                {id: 'x-axis', name: 'X-Axis', selection: 'range'},
              ]
            },
            {
              id: 'line-chart',
              name: 'Line Chart',
              image: 'img/charts/graph-33.png',
              description: "Line chart description",
              dimensions: [
                {id: 'x-axis', name: 'X-Axis', selection: 'range'},
              ]
            },
            {
              id: 'bar-chart',
              name: 'Bar Chart',
              image: 'img/charts/graph-1.png',
              description: "Bar chart description",
              dimensions: [
                {id: 'x-axis', name: 'X-Axis', selection: 'range'},
              ]
            },
            {
              id: 'donut-chart',
              name: 'Donut Chart',
              image: 'img/charts/graph-2.png',
              description: "Donut chart description",
              dimensions: [
                {id: 'donut', name: 'Donut', selection: 'range', weighted: true},
              ]
            }
          ];
  
          var model = {
            model: '',
            name: '',
            description: '',
            from: '',
            to: '',
            geographies: [],
            indicators: [],
            data: []
          };
  
  
  
          // localStorageService.remove(cacheKey);
  
          dataFactory.list = function(params) {
              return $http.get(urlBase + '/geomodel/', {
                  params: params
              });
          };
  
          dataFactory.get = function(params) {
              return $http.get(urlBase + '/geomodel/' + params.id);
          };
  
          function getPostModel(model) {
            var m = {};
            m.name = model.name;
            if(typeof model.id !== 'undefined' && model.id) {
              m.id = model.id;
            }
            m.algorithm_code = model.modelType.name;
            m.description = model.description;
            m.content = JSON.stringify(model);
            return m;
          }
  
          dataFactory.localSave = function(model) {
            localStorageService.set(cacheKey, model);
          }
  
          dataFactory.getLocalModel = function() {
            return localStorageService.get(cacheKey);
          }
  
          dataFactory.getValues = function(params) {
              return $http.get(urlBase + '/geomodel/values', {
                  params: params
              });
          };
  
          dataFactory.new = function(params) {
              return $http.get(urlBase + '/geomodel/new', {
                  params: params
              });
          };
  
          dataFactory.replace = function(data) {
              var m = getPostModel(data);
              return $http.put(urlBase + '/geomodel/replace', m);
          };
  
          dataFactory.getIndicators = function(params) {
              return $http.get(urlBase + '/geomodel/indicators', {
                  params: params
              });
          };
  
          dataFactory.addCountry = function(country) {
  
          }
  
          dataFactory.addIndicatior = function(indicator) {
  
          }
  
          dataFactory.getModelTypes = function() {
            return modelTypes;
          }
  
          dataFactory.start = function() {
            dataFactory.localSave(model);
          }
  
  
          if(!localStorageService.get(cacheKey)) {
            dataFactory.localSave(model);
          }
  
          return dataFactory;
      }]);
  
  angular.module('MRT')
          .factory('vsModelHydratorService', ['$http', '$filter', 'env', 'localStorageService', function($http, $filter, env, localStorageService) {
  
          var hydrator = {};
  
          hydrator.getAxis = function(groups) {
            var axis = {};
            for(var i = 0; i < groups.length; i++) {
              var indicators = groups[i].indicators;
              axis[groups[i].dimension] = {name: '', code: ''};
              if(indicators.length) {
                axis[groups[i].dimension].name = indicators[0].name;
                axis[groups[i].dimension].code = indicators[0].code;
              }
            }
            return axis;
          }
  
          function getDate(dt) {
  
            var d = new Date(dt);
              if(d && typeof d.getFullYear !== 'undefined') {
                  return d.getFullYear();
              }
              return d;
          }
  
          hydrator.hydrate = function(data) {
  
            var values = data.geographies.sort(function (a,b) {return d3.ascending(a.name, b.name);});
  
            var axis = hydrator.getAxis(data.indicators);
            axis.min = getDate(data.from)-1;
            axis.max = getDate(data.to);
  
            for(var i = 0; i < values.length; i++) {
              angular.forEach(axis, function(indicator, dimensionKey) {
                values[i][dimensionKey] = getCountryValues(values[i].code, indicator.code, dimensionKey, data.indicators);
              });
            }
  
            angular.forEach(axis, function(indicator, key) {
  						axis[key].maxValue = d3.max(values, function(c) {
  								return d3.max(c[key], function(v) { return v[1]; });
  						});
  						axis[key].minValue = d3.min(values, function(c) {
  								return d3.min(c[key], function(v) { return v[1]; });
  						});
  					});
  
            return {data: values, axis: axis};
  
          }
  
  
          function filterCountryValues(indicator, countryCode) {
            var values = [];
                if(indicator.geographies.length) {
                  var geography = $filter('filter')(indicator.geographies, {code: countryCode}, true);
                  if(geography.length) {
                    values = createValueArray(geography[0].values);
                  }
                }
            return values;
          }
  
          function createValueArray(data) {
            var values = [];
            for(var i = 0; i < data.length; i++) {
              var row = data[i];
              if(row.labelType === 'date') {
                if(row.value !== '-') {
                  values.push([parseInt(row.label), row.value]);
                }
  
              }
            }
            return values.sort(function(a,b) { return d3.ascending(a[0], b[0]); })
          }
  
          function getCountryValues(countryCode, indicatorCode, dimension, groups) {
            var countryValues = [];
            for(var i = 0; i < groups.length; i++) {
              var group = groups[i];
              if(group.dimension === dimension) {
                var indicators = $filter('filter')(group.indicators, {code: indicatorCode}, true);
                if(indicators.length) {
                  countryValues = filterCountryValues(indicators[0], countryCode);
                }
  
              }
  
            }
  
            return countryValues;
          }
  
          return hydrator;
      }]);
  
  /**
  * Loading Directive
  * @see http://tobiasahlin.com/spinkit/
  */
  angular
  .module('MRT')
  .directive('rdLoading', rdLoading);
  function rdLoading() {
  var directive = {
  restrict: 'AE',
  template: '<div class="loading"><div class="double-bounce1"></div><div class="double-bounce2"></div></div>'
  };
  return directive;
  };
  /**
   * Widget Body Directive
   */
  angular
  		.module('MRT')
  		.directive('rdWidgetBody', rdWidgetBody);
  function rdWidgetBody() {
  	var directive = {
  		requires: '^rdWidget',
  		scope: {
  			loading: '@?',
  			classes: '@?'
  		},
  		transclude: true,
  		template: '<div class="widget-body" ng-class="classes"><rd-loading ng-show="loading"></rd-loading><div ng-hide="loading" class="widget-content" ng-transclude></div></div>',
  		restrict: 'E'
  	};
  	return directive;
  }
  ;
  /**
  * Widget Footer Directive
  */
  angular
  .module('MRT')
  .directive('rdWidgetFooter', rdWidgetFooter);
  function rdWidgetFooter() {
  var directive = {
  requires: '^rdWidget',
  transclude: true,
  template: '<div class="widget-footer" ng-transclude></div>',
  restrict: 'E'
  };
  return directive;
  };
  /**
   * Widget Header Directive
   */
  
  angular
      .module('MRT')
      .directive('rdWidgetHeader', rdWidgetTitle);
  
  function rdWidgetTitle() {
      var directive = {
          requires: '^rdWidget',
          scope: {
              title: '@',
              icon: '@'
          },
          transclude: true,
          template: '<div class="widget-header"><i class="fa" ng-class="icon"></i> {{title}} <div class="pull-right" ng-transclude></div></div>',
          restrict: 'E'
      };
      return directive;
  };
  /**
   * Widget Directive
   */
  
  angular
      .module('MRT')
      .directive('rdWidget', rdWidget);
  
  function rdWidget() {
      var directive = {
          transclude: true,
          template: '<div class="widget" ng-transclude></div>',
          restrict: 'EA'
      };
      return directive;
  
      function link(scope, element, attrs) {
          /* */
      }
  };
  (function() {
      'use strict';
  
      angular
          .module('MRT')
          .controller('GeoModelCreateCountrySelection', GeoModelCreateCountrySelection);
      GeoModelCreateCountrySelection.$inject = ['$scope', '$filter', '$stateParams', '$modal', '$log', '$state', 'ngNotify', 'geoModelService', 'geoGroupService', 'geographyService'];
  
      function GeoModelCreateCountrySelection($scope, $filter, $stateParams, $modal, $log, $state, ngNotify, geoModelService, geoGroupService, geographyService) {
        var vm = this;
        $scope.data = {};
        $scope.options = {};
        $scope.options.selectType = "group";
        $scope.data.geographies = [];
        $scope.data.geogroups = [];
  
        $scope.chartOptions = {};
        $scope.chartOptions.data = {};
        $scope.toggleSelection = toggleSelection;
        $scope.toggleGroupExpand = toggleGroupExpand;
        $scope.toggleGroupSelect = toggleGroupSelect;
        $scope.countSelected = countSelected;
        $scope.clear = clear;
        $scope.go = go;
        var model = geoModelService.getLocalModel();
        $scope.model = model;
        // console.log(model);
  
        geographyService.getGeographies({}).success(function(data) {
            $scope.data.geographies = tickSelectedGeographies(data.geographies);
            loadGroups();
        }).error(function(error) {
            $scope.status = 'Unable to load customer data: ' + error.message;
        });
  
        function tickSelectedGeographies(geographies) {
          for(var i = 0; i < geographies.length; i++) {
            var found = $filter('filter')(model.geographies, {id: parseInt(geographies[i].id)}, true);
            if (found.length) {
              geographies[i].selected = true;
              chartSelect(geographies[i].code_3);
            } else {
              geographies[i].selected = false;
            }
          }
          $scope.chartOptions.updated = Date.now();
  
          return geographies;
        }
  
        function saveGeographies() {
          model.geographies = [];
          var geographies = $scope.data.geographies;
          for(var i = 0; i < geographies.length; i++) {
            if(geographies[i].selected === true) {
              model.geographies.push(geographies[i]);
            }
          }
          geoModelService.localSave(model);
        }
  
        function go(page, params) {
          var found = $filter('filter')($scope.data.geographies, {selected: true}, true);
          if(!found.length) {
            ngNotify.set("Select 1 or more coutries", {
              position: 'top',
              type: 'error',
              duration: 2000
            });
            return false;
          }
          if(typeof params === 'undefined') {
            params = {};
          }
          saveGeographies();
          $state.go(page, params);
        }
  
  
  
  
        function loadGroups() {
        geoGroupService.list({}).success(function(data) {
            $scope.data.geogroups = [];
            var length = data.geogroups.length;
            for(var i = 0; i < length; i++) {
              data.geogroups[i].loaded = false;
              data.geogroups[i].selected = false;
              data.geogroups[i].expand = false;
              data.geogroups[i].children = [];
              $scope.data.geogroups.push(data.geogroups[i]);
            }
        }).error(function(error) {
            $scope.status = 'Unable to load customer data: ' + error.message;
        });
      }
  
        var data = {
  				USA: {fillKey: 'lt50' },
  				RUS: {fillKey: 'lt50' },
  				MLI: {fillKey: 'lt50' },
  				BRA: {fillKey: 'lt50' },
  				ARG: {fillKey: 'lt50'},
  				COL: {fillKey: 'lt50' },
  				AUS: {fillKey: 'lt50' },
  				ZAF: {fillKey: 'lt50' },
  				SWE: {fillKey: 'lt50' }
  			};
  
  
        var country = {};
  
        function clear() {
  
          for (var key in $scope.chartOptions.data) {
            if ($scope.chartOptions.data.hasOwnProperty(key)) {
              $scope.chartOptions.data[key].fillKey = "defaultFill";
            }
          }
          var length = $scope.data.geographies.length;
          for(var i = 0; i < length; i++) {
            $scope.data.geographies[i].selected = false;
          }
          resetGroupSelection();
          $scope.chartOptions.updated = Date.now();
        }
  
        function countSelected(row) {
          var $return = 0;
          var children = row.children
          var length = children.length;
          var child;
          for(var i = 0; i < length; i++) {
            if(children[i].selected === true) {
              $return++;
            }
          }
          return $return > 0 ? $return : '';
        }
  
        function resetGroupSelection() {
          var groups = $scope.data.geogroups;
          var length = groups.length;
          var group;
          var cLength;
          for(var i = 0; i< length; i++) {
            group = groups[i];
            group.selected = false;
            cLength = group.children.length;
            for(var ii = 0; ii < cLength; ii++) {
              group.children[ii].selected = false;
            }
  
          }
        }
  
  
  
        function toggleSelection(code, selected) {
          togggleChartSelection(code, selected);
          var length = $scope.data.geographies.length;
  
          for(var i = 0; i < length; i++) {
            country =  $scope.data.geographies[i];
            if(country.code_3 === code) {
              if(typeof selected !== "undefined") {
                country.selected = selected;
              } else {
                country.selected = (country.selected === "undefined") ? true : !country.selected;
              }
  
            }
          }
          $scope.chartOptions.updated = Date.now();
        }
  
  
        function chartSelect(code) {
          $scope.chartOptions.data[code] = {fillKey: 'selectedFill'};
        }
  
        function chartDeSelect(code) {
          $scope.chartOptions.data[code] = {fillKey: 'defaultFill'};
        }
  
        function togggleChartSelection(code, selected) {
          if(typeof selected !== "undefined") {
            $scope.chartOptions.data[code] = selected === true ? {fillKey: 'selectedFill'} : {fillKey: 'defaultFill'};
          } else if(typeof $scope.chartOptions.data[code] === "undefined") {
            $scope.chartOptions.data[code] = {fillKey: 'selectedFill'};
          } else {
            $scope.chartOptions.data[code].fillKey = $scope.chartOptions.data[code].fillKey === "selectedFill" ? "defaultFill" : "selectedFill";
          }
        }
  
        function toggleGroupExpand(group) {
          if(group.loaded !== true) {
            loadChildren(group);
          }
          group.expand = !group.expand;
        }
  
        function toggleGroupSelect(group) {
          // group.selected = !group.selected;
          console.log("toggle group");
          if(group.loaded !== true) {
            loadChildren(group, true);
          } else {
            _toggleGroupSelect(group);
          }
  
        }
  
        function _toggleGroupSelect(group) {
          var length = group.children.length;
          // if(group.selected === true) {
            for(var i = 0; i < length; i++) {
              group.children[i].selected = group.selected === true ? false : true;
              toggleSelection(group.children[i].code_3, group.selected);
            }
          // }
        }
  
  
        function loadChildren(group, toggleGroupExpand) {
          geoGroupService.getGeographies({id: group.id}).success(function(data) {
            var g = data.group;
            var geographies = data.geographies;
            var length = geographies.length;
            var geography;
            for(var i = 0; i < length; i++) {
              geography = geographies[i];
              var found = $filter('filter')($scope.data.geographies, {id: parseInt(geography.geography_id)}, true);
              if (found.length) {
                group.children.push(found[0]);
              } else {
              }
            }
            group.loaded = true;
            if(typeof toggleGroupExpand !== "undefined" && toggleGroupExpand === true) {
              _toggleGroupSelect(group);
            }
  
          }).error(function(error) {
            $scope.status = 'Unable to load customer data: ' + error.message;
          });
        }
  
  
      }
  })();
  
  (function() {
      'use strict';
  
      angular
          .module('MRT')
          .controller('GeoModelCreateIndicatorSelection', GeoModelCreateIndicatorSelection);
      GeoModelCreateIndicatorSelection.$inject = ['$scope', '$filter', '$stateParams', '$modal', '$log',  '$state', 'geoModelService', 'geoIndicatorGroupService', 'geoIndicatorService'];
  
      function GeoModelCreateIndicatorSelection($scope, $filter, $stateParams, $modal, $log, $state, geoModelService, geoIndicatorGroupService, geoIndicatorService) {
        var vm = this;
        $scope.data = {};
        $scope.options = {};
        $scope.options.selectType = "group";
        $scope.data.indicators = [];
        $scope.data.groups = [];
        $scope.ui = {};
        $scope.ui.loadingMesage = null;
        $scope.ui.percentile = percentile;
  
        $scope.balanceGroupWeights = balanceGroupWeights;
        $scope.toggled = function(open) {
      $log.log('Dropdown is now: ', open);
    };
  
  
        $scope.model = geoModelService.getLocalModel();
        $scope.getDate = getDate;
        // $scope.model.data = {};
  
        var defaultIndicator = {name: "Indicator Group", indicators: []};
        // console.log($scope.model);
  
        // $scope.model.data.indicators = defaultIndicator;
  
        $scope.chartOptions = {};
        $scope.toggleSelection = toggleSelection;
        $scope.toggleGroupExpand = toggleGroupExpand;
        $scope.toggleGroupSelect = toggleGroupSelect;
        $scope.countSelected = countSelected;
        $scope.clear = clear;
        $scope.back = back;
        $scope.next = next;
        $scope.addIndicatorGroup = addIndicatorGroup;
        $scope.addIndicatorGroupToDimension = addIndicatorGroupToDimension;
        $scope.addIndicatorToGroup = addIndicatorToGroup;
        $scope.copyIndicatorGroup = copyIndicatorGroup;
        $scope.selectDimension = selectDimension;
        $scope.loadIndicatorValues = loadIndicatorValues;
        $scope.selectedIndicator = null;
        $scope.selectIndicator = selectIndicator;
        $scope.getValues = getValues;
        $scope.reloadAll = reloadAll;
        var model = geoModelService.getLocalModel();
  
        console.log(model);
  
        loadUnweightedIndicatorGroups($scope.model);
        loadModelIndicatorValues($scope.model);
        loadIndicators();
  
  
  
        function percentile(percentage, block, upper) {
          if(typeof upper === "undefined") {
            upper = 100 ;
          }
  
          if(typeof block === "undefined") {
            block = 4 ;
          }
  
          upper = percentage > upper ? percentage : upper;
          var result = Math.ceil(percentage/(upper/block))
          return result <= 0 ? 1 : result;
        }
  
        function loadIndicators() {
        geoIndicatorService.getGeoIndicators({}).success(function(data) {
            $scope.data.indicators = data.geoindicators;
            loadGroups();
        }).error(function(error) {
            $scope.status = 'Unable to load customer data: ' + error.message;
        });
  
      }
  
      function selectIndicator(indicator) {
        $scope.selectedIndicator = indicator;
      }
  
      function getGeographyIds(geographies) {
        var ids = [];
        for(var i = 0; i < geographies.length; i++) {
          ids.push(geographies[i].id);
        }
        return ids;
      }
  
      function loadModelIndicatorValues(model, load) {
        var indicators;
        var groups;
        var indicator;
        if(typeof model.reload !== "undefined" && model.reload === true) {
          load = true;
          model.reload = false;
        }
        for(var i = 0; i < model.indicators.length; i++) {
          groups = model.indicators[i];
  
          for(var ii = 0; ii < groups.indicators.length; ii++) {
            indicator = groups.indicators[ii];
            indicator = appendIndicatorDates(model, indicator);
            if(typeof load !== "undefined" && load == true) {
              indicator.loaded = false;
            }
            loadIndicatorValues(model.geographies, indicator);
          }
        }
      }
  
      function balanceGroupWeights(groups, dimensions) {
  
        console.log(groups);
        for(var i = 0; i < groups.length; i++) {
            var group =  groups[i];
            var dimension = $filter('filter')(dimensions, {id: group.dimension}, true);
            // console.log(group);
            if(dimension.length) {
              balanceIndicatorWeights(group.indicators, dimension[0].weight);
            }
  
        }
  
      }
  
      function balanceIndicatorWeights(indicators, weight) {
  
        weight = parseFloat(weight);
        var weightTotal = 0;
        for(var i = 0; i < indicators.length; i++) {
            var indicator =  indicators[i];
            if(typeof indicator.weight === 'undefined' || !indicator.weight) {
              indicator.weight = 0;
            }
            console.log(indicator.weight);
            console.log(weight);
            indicator.weight = parseFloat(indicator.weight);
            weightTotal += indicator.weight;
        }
  
        for(var i = 0; i < indicators.length; i++) {
            var indicator =  indicators[i];
            indicator.weight = (indicator.weight/weightTotal)*weight;
            console.log(indicator.weight);
        }
  
      }
  
      function reloadAll(model) {
        loadModelIndicatorValues(model, true);
      }
  
      function loadIndicatorValues(geographies, indicator) {
        if(typeof indicator.loaded === "undefined") {
          indicator.loaded = false;
        }
  
        if(indicator.loaded !== true) {
          getValues(geographies, indicator);
        }
      }
  
      function appendIndicatorDates(model, indicator) {
        if(typeof indicator.from === "undefined") {
          indicator.from = getDate(model.from);
        }
        if(typeof indicator.to === "undefined") {
          indicator.to = getDate(model.to);
        }
        return indicator;
      }
  
      function getValues(geographies, indicator) {
          var params = {};
          indicator = appendIndicatorDates($scope.model, indicator);
          indicator.loading = true;
          params.from = getDate(String(indicator.from));
          params.to = getDate(String(indicator.to));
          params.id = indicator.id;
          params["geography_ids[]"] = getGeographyIds(geographies);
          geoIndicatorService.getGeoIndicatorValues(params).success(function (data) {
              indicator.loading = false;
              indicator.loaded = true;
              updateIndicatorValues(data[0], indicator);
          }).error(function (error) {
              $scope.status = 'Unable to load customer data: ' + error.message;
          });
  
      }
  
      function loadUnweightedIndicatorGroups(model) {
        var dimensions = model.modelType.dimensions;
          for(var i = 0; i < dimensions.length; i++) {
            if(typeof dimensions[i].weighted === "undefined" || dimensions[i].weighted != true) {
              var dimension = dimensions[i];
              var indicatorGroup = $filter('filter')(model.indicators, {dimension: dimension.id}, true);
              if(!indicatorGroup.length) {
                addIndicatorGroupToDimension(dimension, dimension.name);
              } else {
                indicatorGroup[0].name = dimension.name;
              }
            }
  
          }
      }
  
  
      function updateIndicatorValues(data, indicator) {
        indicator.dates = data.dates;
        indicator.geographies = geoIndicatorService.hydrateValues(data.values, data.dates, data.geographies);
        indicator.summary = geoIndicatorService.getSummary(indicator.geographies);
      }
  
      function getDate(dt) {
  
        var d = new Date(dt);
          if(d && typeof d.getFullYear !== 'undefined') {
              return d.getFullYear();
          }
          return d;
      }
  
      function getNewIndicator() {
        var indicator = angular.copy(defaultIndicator);
        var length = $scope.model.indicators.length+1;
        var selectedDimension = getSelectedDimension();
        indicator.name = indicator.name + " " + length;
        indicator.id = "id" + length;
        indicator.dimension = selectedDimension.id;
        return indicator;
      }
  
      function getSelectedDimension() {
        return $scope.model.selectedDimension;
      }
  
  
      function addIndicatorGroup(name) {
        var group = getNewIndicator();
        if(typeof name !== "undefined") {
          group.name = name;
        }
        $scope.model.indicators.push(getNewIndicator());
      }
  
      function addIndicatorGroupToDimension(dimension, name) {
        var indicator = getNewIndicator();
        indicator.dimension = dimension.id;
        if(typeof name !== "undefined") {
          indicator.name = name;
        }
        $scope.model.indicators.push(indicator);
      }
  
  
  
      function addIndicatorToGroup(indicator, group) {
        var indicatorCopy = angular.copy(indicator);
        var found = $filter('filter')(group.indicators, {code: indicatorCopy.code}, true);
        if(!found.length) {
  
          group.indicators.push(indicatorCopy);
          loadIndicatorValues(model.geographies, indicatorCopy);
  
        }
      }
  
      $scope.remove = function(items, item) {
        var index = items.indexOf(item);
        items.splice(index, 1);
      }
  
      function copyIndicatorGroup(group, dimension) {
        loadChildren(group, false, function() {
          var indicator = getNewIndicator();
          indicator.name = angular.copy(group.name);
          if(typeof dimension !== "undefined") {
            indicator.dimension = dimension.id;
          }
          $scope.model.indicators.push(indicator);
          for(var i = 0; i < group.children.length; i++) {
            addIndicatorToGroup(group.children[i], indicator);
          }
          // indicator.indicators = angular.copy(group.children);
          // console.log(indicator);
  
        });
  
      }
  
  
  
      function loadGroups() {
        geoIndicatorGroupService.list({}).success(function(data) {
            $scope.data.groups = [];
            var length = data.groups.length;
            for(var i = 0; i < length; i++) {
              data.groups[i].loaded = false;
              data.groups[i].selected = false;
              data.groups[i].expand = false;
              data.groups[i].children = [];
              $scope.data.groups.push(data.groups[i]);
            }
        }).error(function(error) {
            $scope.status = 'Unable to load customer data: ' + error.message;
        });
      }
  
        var data = {
  				USA: {fillKey: 'lt50' },
  				RUS: {fillKey: 'lt50' },
  				MLI: {fillKey: 'lt50' },
  				BRA: {fillKey: 'lt50' },
  				ARG: {fillKey: 'lt50'},
  				COL: {fillKey: 'lt50' },
  				AUS: {fillKey: 'lt50' },
  				ZAF: {fillKey: 'lt50' },
  				SWE: {fillKey: 'lt50' }
  			};
  
        $scope.chartOptions.data = {};
        var country = {};
  
        function clear() {
  
          for (var key in $scope.chartOptions.data) {
            if ($scope.chartOptions.data.hasOwnProperty(key)) {
              $scope.chartOptions.data[key].fillKey = "defaultFill";
            }
          }
          var length = $scope.data.geographies.length;
          for(var i = 0; i < length; i++) {
            $scope.data.geographies[i].selected = false;
          }
          resetGroupSelection();
          $scope.chartOptions.updated = Date.now();
        }
  
        function back() {
          geoModelService.localSave(model);
          $state.go("geomodel-create-country-selection");
        }
  
        function selectDimension(dimension) {
          $scope.model.selectedDimension = dimension;
        }
  
        function next() {
  
          // model = $scope.model.indicators;
          // console.log(JSON.stringify($scope.model));
          geoModelService.localSave($scope.model);
          // console.log($scope.model);
          post($scope.model);
        }
  
        function post(model) {
          geoModelService.replace(model).success(function(data) {
              // console.log(data);
              $state.go("geomodel-vs-model", {id: parseInt(data.id)});
          }).error(function(error) {
              // $state.go("geomodel-vs-model", {id: data});
          });
        }
  
        function countSelected(row) {
          var $return = 0;
          var children = row.children
          var length = children.length;
          var child;
          for(var i = 0; i < length; i++) {
            if(children[i].selected === true) {
              $return++;
            }
          }
          return $return > 0 ? $return : '';
        }
  
        function resetGroupSelection() {
          var groups = $scope.data.geogroups;
          var length = groups.length;
          var group;
          var cLength;
          for(var i = 0; i< length; i++) {
            group = groups[i];
            group.selected = false;
            cLength = group.children.length;
            for(var ii = 0; ii < cLength; ii++) {
              group.children[ii].selected = false;
            }
  
          }
        }
  
  
        function toggleSelection(row, parent) {
          if(typeof row.selected == "undefined") {
            row.selected = false;
          }
          row.selected = !row.selected;
  
          var indicator = angular.copy(row);
          var group = angular.copy(parent);
          if(typeof parent !== "undefined") {
            addIndicator(indicator, group);
          }
        }
  
        function addIndicator(indicator, group) {
          var modelIndicators = $scope.model.data.indicators;
          var length = modelIndicators.length;
          var selectedGroup = null;
          for(var i = 0; i < length; i++) {
            if(modelIndicators[i].id === group.id) {
              selectedGroup = i;
            }
          }
  
          if(selectedGroup !== null) {
            addIndicatorToModelGroup(indicator, selectedGroup);
          }
  
        }
  
        /**
        * add to model indicator groups
        **/
        function addIndicatorToModelGroup(indicator, group) {
          var length = group.indicators.length;
          for(var i = 0; i < length; i++) {
            group.indicators.push(indicator);
          }
        }
  
  
  
        function togggleChartSelection(code) {
          if(typeof $scope.chartOptions.data[code] === "undefined") {
            $scope.chartOptions.data[code] = {fillKey: 'selectedFill'};
          } else {
            $scope.chartOptions.data[code].fillKey = $scope.chartOptions.data[code].fillKey === "selectedFill" ? "defaultFill" : "selectedFill";
          }
        }
  
        function toggleGroupExpand(group) {
          if(group.loaded !== true) {
            loadChildren(group);
          }
          group.expand = !group.expand;
        }
  
        function toggleGroupSelect(group) {
          // group.selected = !group.selected;
          if(group.loaded !== true) {
            loadChildren(group, true);
          } else {
            _toggleGroupSelect(group);
          }
        }
  
        function _toggleGroupSelect(group) {
          var length = group.children.length;
          // if(group.selected === true) {
            for(var i = 0; i < length; i++) {
              group.children[i].selected = group.selected;
              // toggleSelection(group.children[i].id);
            }
          //}
        }
  
  
        function loadChildren(group, toggleGroupExpand, callback) {
          geoIndicatorGroupService.getIndicators({id: group.id}).success(function(data) {
            var g = data.group;
            var indicators = data.indicators;
            var length = indicators.length;
            var indicator;
            for(var i = 0; i < length; i++) {
              indicator = indicators[i];
              var found = $filter('filter')($scope.data.indicators, {id: indicator.geoindicator_id}, true);
              if (found.length) {
                group.children.push(found[0]);
              } else {
              }
            }
            group.loaded = true;
            if(typeof toggleGroupExpand !== "undefined" && toggleGroupExpand === true) {
              _toggleGroupSelect(group);
            }
  
            if(typeof callback !== "undefined") {
              callback();
            }
  
  
          }).error(function(error) {
            $scope.status = 'Unable to load customer data: ' + error.message;
          });
        }
  
  
      }
  })();
  
  (function() {
    'use strict';
  
    angular
    .module('MRT')
    .controller('GeoModelCreateModel', GeoModelCreateModel);
    GeoModelCreateModel.$inject = ['$scope', '$filter', '$stateParams', '$modal', '$log', '$state', '$interval', 'ngNotify', 'geoModelService', 'geoIndicatorGroupService', 'geoIndicatorService'];
  
    function GeoModelCreateModel($scope, $filter, $stateParams, $modal, $log, $state, $interval, ngNotify, geoModelService, geoIndicatorGroupService, geoIndicatorService) {
      var vm = this;
      $scope.modelTypes = geoModelService.getModelTypes();
      $scope.options = {};
      $scope.options.models = [
        {'id': 'mckinsey-matrix', 'name': 'GE McKinsey 9 Box Matrix'},
        {'id' : 'bg-matrix', 'name': 'BG Matrix'}
      ];
      var constraints = {
        name: {
          presence: true,
          length: {
            minimum: 3,
            message: " is too short"
          }
        },
        selectedDimension: {
          presence: true
        },
        from: {
          presence: true
        },
        to: {
          presence: true
        }
      };
  
  
  
      if($stateParams.id) {
        if($stateParams.id === 'local') {
          $scope.model = geoModelService.getLocalModel();
        } else if($stateParams.type === 'copy') {
          copyModel($stateParams.id);
        } else {
          loadModel($stateParams.id);
        }
  
      } else {
        geoModelService.start();
        $scope.model = geoModelService.getLocalModel();
      }
  
      $scope.next = next;
      $scope.selectModelType = selectModelType;
  
      function loadModel(id) {
        geoModelService.get({id: id}).success(function(data) {
          var model = JSON.parse(data.content);
          model.id = data.id;
          geoModelService.localSave(model);
  
          $scope.model = geoModelService.getLocalModel();
        }).error(function(error) {
          $scope.status = 'Unable to load customer data: ' + error.message;
        });
      }
  
      function copyModel(id) {
        geoModelService.get({id: id}).success(function(data) {
          var model = JSON.parse(data.content);
          if(typeof model.id !== undefined) {
            model.id = null;
          }
          model.name = 'Copy of ' + model.name;
          model.reload = true;
          geoModelService.localSave(model);
          $scope.model = geoModelService.getLocalModel();
        }).error(function(error) {
          $scope.status = 'Unable to load customer data: ' + error.message;
        });
      }
  
      function next() {
        var errors = validate($scope.model, constraints, {format: "flat"});
        if(errors && errors.length) {
          ngNotify.set(errors[0], {
            position: 'top',
            type: 'error',
            duration: 2000
          });
          return false;
        }
        if(typeof $scope.model.modelType == "undefined") {
          selectModelType($scope.modelTypes[0]);
        }
        geoModelService.localSave($scope.model);
        $state.go("geomodel-create-country-selection");
  
  
      }
  
  
  
      // need to move this to service
      function selectModelType(modelType) {
        $scope.model.modelType = modelType;
        if(typeof $scope.model.selectedDimension === "undefined") {
          $scope.model.selectedDimension = modelType.dimensions[0];
        }
      }
  
      $scope.today = function() {
        $scope.dt = new Date();
      };
      $scope.today();
  
      $scope.clear = function () {
        $scope.dt = null;
      };
  
  
      $scope.disabled = function(date, mode) {
        return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
      };
  
      $scope.toggleMin = function() {
        $scope.minDate = $scope.minDate ? null : new Date();
      };
      $scope.toggleMin();
  
      $scope.openFrom = function($event) {
        $event.preventDefault();
        $event.stopPropagation();
  
        $scope.fromOpened = true;
      };
  
      $scope.openTo = function($event) {
        $event.preventDefault();
        $event.stopPropagation();
  
        $scope.toOpened = true;
      };
  
  
  
  
  
      $scope.initDate = new Date('2016-15-20');
      $scope.formats = ['yyyy','dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
      $scope.format = $scope.formats[0];
  
      $scope.datepickerOptions = {
        datepickerMode:"'year'",
        minMode:"'year'",
        maxMode:"'year'",
        //minDate:"minDate",
        showWeeks:"false",
      };
  
  
  
  
    }
  })();
  
  (function() {
      'use strict';
  
      angular
          .module('MRT')
          .controller('GeoModelVsModel', GeoModelVsModel);
      GeoModelVsModel.$inject = ['$scope', '$filter', '$stateParams', '$modal', '$log', '$state', 'geoModelService', 'geoIndicatorGroupService', 'geoIndicatorService', 'vsModelHydratorService'];
  
      function GeoModelVsModel($scope, $filter, $stateParams, $modal, $log, $state, geoModelService, geoIndicatorGroupService, geoIndicatorService, vsModelHydratorService) {
        var vm = this;
        $scope.options = {};
        $scope.model = {};
        $scope.ui = {};
        $scope.ui.playing = false;
        $scope.ui.chartData;
  
        loadModel($stateParams.id);
  
        function loadModel(id) {
          geoModelService.get({id: id}).success(function(data) {
              var model = JSON.parse(data.content);
              model.id = data.id;
              geoModelService.localSave(model);
  
              $scope.model = geoModelService.getLocalModel();
              // console.log($scope.model);
              if(model.modelType.id === '3-dimentional-bubble') {
                var result = vsModelHydratorService.hydrate($scope.model);
                $scope.ui.chartData = result;
              }
  
          }).error(function(error) {
              $scope.status = 'Unable to load customer data: ' + error.message;
          });
        }
  
  
      }
  })();
  