
var StringUtilities = {
  addSlashes: function(str) {
    return (str + '').replace(/([\\"'])/g, "\\$1").replace(/\0/g, "\\0");
  },
  
  countBytes: function(text) {
    var count, escapedStr = encodeURI(text);
    if (escapedStr.indexOf("%") != -1) {
      count = escapedStr.split("%").length - 1;
      if (count == 0) count++;  // perverse case; can't happen with real UTF-8
      count += (escapedStr.length - (count * 3));
    } else {
      count = escapedStr.length;
    }
    return count;
  }
};



var $ = jQuery.noConflict();

var url_WebSelfCare = "/WebSelfCare/",
    url_Responder = url_WebSelfCare + "work.html",
    url_WARoot = url_WebSelfCare + "Interfaces/CareM/",
    url_Images = url_WARoot + "IMG/",
    url_ServiceInfoDir = url_WARoot + "/XSL/ServiceProfile/",
    url_RegistrationModule = "https://authority.o.kg:8443/registration/work.html",
    url_OkgFiles = "http://www.o.kg/files/";

var SelfCare_RegEx = {
  number: /^(?:\-|\+)?\d+$/,
  unsigned: /^\+?\d+$/,
  msisdn: /^(0|\+?996)70\d{7}$/,
  email: /^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i
};

$.ajaxSetup({
  url: url_Responder,
  dataType: "html",

  error: function() {
    alert("Соединение с сервером потерянно");
  }
});

var SelfCare =
{
  // session id
  SID3: null,
  
  /**
   * Build out context query string.
   *
   * @param context string ['page', 'content', (any custom)]
   * @param params array
   */
  buildOutContextQuery: function(context, params)
  {
    var param_list = [];
    
    if (typeof params != 'undefined')
    {
      context += '?';
      
      for (var name in params) {
        param_list.push(name + '=' + params[name]);
      }
    }
    
    return context + param_list.join('&');
  },
  
  loading_in_process: false,

  /**
   * Ajax request function.
   *
   * @param command string SLR operation [_root/n/n | _next | _cancel | ...]
   * @param params array|object SLR command params [user_input_1, 2, 3...] or {user_input_1: param[0], user_input_2: param[1]..., user_input_last: outcontext}
   * @param outcontext string query string build using SelfCare.buildContextQuery()
   * @param oncomplete callback(string status[success|ajax_busy|error], (jquery $html|string error), [error_exception])
   * @param prevent_default_rh boolean when sets to true - calling a default response handler will be prevented
   * @return boolean true - if the request was sent or else - otherwise
   */
  request: function(command, params, outcontext, oncomplete, prevent_default_rh)
  {
    var data = {
      user_input_0: command || '_root/1/1' // default action
    };
    
    if (SelfCare.SID3) {
      data.sid3 = SelfCare.SID3;
    }
    
    if (typeof params != 'undefined')
    {
      if (params instanceof Array)
      {
        if (typeof outcontext == 'string' || typeof outcontext == 'number') {
          data.user_input_1 = outcontext;
        } else {
          data.user_input_1 = 'page'; // default outcontext
        }

        var i = 0;
        for (; i < params.length; i++) {
          data['user_input_' + (2 + i)] = params[i];
        }
        oncomplete = oncomplete || null;
      }
      else {
        /* when an object given as a named params dictionary,
           expects that outcontext given as a first param in it */
        if (params !== null) {
          var key;
          for (key in params) {
            data[key] = params[key];
          }
        }
        // and uses outcontext argument as an oncomplete callback
        oncomplete = outcontext || null;
      }
    }
    
    if (this.loading_in_process) {
      if (oncomplete) { oncomplete.call(SelfCare, 'ajax_busy', 'request in process'); oncomplete = null; }
      return false;
    }
    
    this.loading_in_process = true;

    $('#global_loading_indicator:hidden').show();
    $('#global_loading_indicator').stop().fadeTo('fast', 1);

    data.user_input_timestamp = (new Date).getTime();

    $.ajax({
      type: 'POST',
      data: data,
      
      success: function(response)
      {
        var $response = $(response);
        
        // processing static action
        if ($response.is('#StaticAction'))
        {
          $response.children('#static_action_content').appendTo('body');
          
          $('#static_action_enter_button')
            .one('click', function() { SelfCare.request(); });
          
          window.PageShader.hide()
            .show('#static_action_content', 300, 170)
            .onhide(function() {
              $('#static_action_content').remove();
            });
        }

        // processing response
        else if ($response.is("#Response"))
        {
          // updating session id
          var $sid3 = $response.children("#Sid3");
          if ($sid3.length) {
            SelfCare.SID3 = $sid3.text();
          }

          if (typeof prevent_default_rh == "undefined" || !prevent_default_rh) {
            var context;
            if (typeof data.user_input_1 != "undefined") {
              context = data.user_input_1;
            }
            else {
              var match = /^_cancel\/([^\/]+)(?:\/?|$)/.exec(data.user_input_0);
              context = match ? match[1] : "page";
            }
            SelfCare.loadResponse($response, context);
          }
          
          if (oncomplete) { oncomplete.call(SelfCare, "success", $response); oncomplete = null; }
        }

        else if ($response.is("response")) {
          window.location.href = "?use=2.0";
        }

        else {
          console.error("Unknown response format", $response[0]);
        }
      },
      
      error: function() {
        if (oncomplete) { oncomplete.apply(this, arguments); oncomplete = null; }
      },

      complete: function() {
        SelfCare.loading_in_process = false;
        $("#global_loading_indicator").stop().fadeTo("fast", 0, function() { $(this).hide(); });
      }
    });
    
    return true;
  },

  loadResponse: function($response, context)
  {
    context = context ? context.split('?')[0] : null;
    
    window.PageShader.hide();

    var $op_notification = $response.children("#OperationNotification");
    if ($op_notification.length) {
      alert($op_notification.text());
    }
    
    var inContext = $response.children("#InContext").text();
    if (inContext == "error") {
      window.setTimeout(function() {
        SelfCare.request("_exit");
      }, 10);
      return;
    }
    
    // megahack for authentication case
    if (context == 'Authentication'
        && $response.children('#AuthenticationStatus').text() != 'failed') {
      context = 'page';
    }

    switch (context) {
      case 'page':
        SelfCare_mainmenu = null;
        
        $('#pagebody').empty()
          .append($response.children('#pagebody').children());

        // running flash-banners
        if ($('#content_bottom:hidden').length) {
          var banners = {1: '183', 2: '192'};
          for (var number in banners) {
            $('#falshbanner_' + number).flash({
              src: url_OkgFiles + banners[number],
              width: 320, height: 300, bgcolor: '#E2007A',
              quality: 'hight', wmode: 'opaque'
            });
          }
          $('#content_bottom').show();
        }
        break;
    
      case 'content':
        $('#contentbody').empty()
          .append($response.find('#contentbody').children());
        break;
    }

    /*var $links = $response.children('link');
    if ($links.length) {
      $links.each(function() {
        if ($htmlhead.children('link[href="' + this.href + '"]').length == 0) { $htmlhead.append(this); }
      });
    }*/
    $('head').append($response.children('script'));
  },

  current_page_handler: null,
  
  load: function(inst) {
    this.current_page_handler = inst;
  }
};


$('.text_block-collapsed .text_block_header,' +
  '.text_block-expanded .text_block_header,' +
  '.text_block-expanded .text_block_collapse_btn')
  .live('click', function() {
    var $collapsed = $(this).closest('.text_block-collapsed');
    if ($collapsed.length) {
      $collapsed.attr('className', 'text_block-expanded');
    } else {
      $(this).closest('.text_block-expanded').attr('className', 'text_block-collapsed');
    }
    return false;
  });

$('.check_all')
  .live('click', function() {
  var $this = $(this),
      check_context = $this.hasClass('check_list') ? 'ul' : 'table',
      checked = this.checked;

  $(this).closest(check_context).find('input[type=checkbox]:not(.check_all)')
    .each(function() {
      if (!this.disabled) { this.checked = checked; }
      $(this).triggerHandler('click'); // TODO: optimize .check_all
    });

  this.checked = checked;
});


// window.PageShader
$(function() {
window.PageShader = new (function()
{
  var $shade_div, $content;

  var clientWidth = $(window).width();
	var clientHeight = $(window).height();

  var shown = false;

  this.show = function(contentElement, width, height)
  {
    if (shown) { return this; }

    $shade_div = $(
      '<div id="page_shader" style="display: none">'+
      '<div id="page_shader_content_host">'+
          '<div class="top-left"></div>'+
          '<div class="top-right"></div>'+
          '<div class="bottom-left"></div>'+
          '<div class="bottom-right"></div>'+
          '<div class="top"></div>'+
          '<div class="right"></div>'+
          '<div class="bottom"></div>'+
          '<div class="left"></div>'+
          '<div id="page_shader_content"/>'+
        '</div>'+
      '</div>'
    ).appendTo('body');

    $content = $('#page_shader_content');

    width = width || 320;
	  height = height || 240;

  	var leftLayer = clientWidth / 2 - width / 2;
	  var topLayer = clientHeight / 2 - height / 2;

    var $contentElement = $(contentElement);

	  if ($contentElement.parent().length) {
	    $contentElement.get(0).oldParent = $contentElement.parent().get(0);
	  }

	  $content.append($contentElement);

  	$shade_div.show();
  	$contentElement.show();

  	$('#page_shader_content_host')
  	  .css({
		    left: leftLayer,
		    top: topLayer,
		    width: width,
		    height: height
      });

  	shown = true;

  	return this;
  };

  this.isShown = function() {
    return shown;
  };


  var onhide;

  this.onhide = function(func) {
    onhide = func;
    return this;
  };
  
  this.hide = function()
  {
    if (!shown) { return this; }

    $shade_div.hide();

    var contentElement = $content.children(0).hide().get(0);

    if (typeof contentElement.oldParent != 'undefined') {
      $(contentElement.oldParent).append(contentElement);
    }
    else {
      $content.empty();
    }

    if (onhide) { onhide(); onhide = null; }

    $shade_div.remove();

    shown = false;

    return this;
  };

});
});


function GroupedListControl(domnode)
{
  var selected = {group: null, item: null};

  var self = this;

  this.getSelectedGroup = function() {
    return selected.group;
  };

  this.getSelectedItem = function() {
    return selected.item;
  };

  this.$list = $(domnode);

  this.$list
    .bind('reset', function()
    {
      if (selected.group) {
        $(selected.group).triggerHandler('deselect');
      }
      else if (selected.item) {
        $(selected.item).triggerHandler('deselect');
      }
    });


  this.$groups = null;

  this.addGroup = function(domnode)
  {
    var $group = $(domnode);

    $group
      .bind('expand', function() {
        $(this).addClass('group-expanded');
      })

      .bind('collapse', function() {
        $(this).removeClass('group-expanded');
      })

      .bind('Select', function() {
        if (selected.group) {
          $(selected.group).triggerHandler('deselect');
        }
        else if (selected.item) {
          var $selected_item = $(selected.item);
          $selected_item.triggerHandler('deselect');
          $selected_item.parents('.group:eq(0)').triggerHandler('collapse');
        }

        selected.group = this;

        $(this).addClass('group-selected').triggerHandler('expand');
      })

      .bind('deselect', function() {
        $(this).removeClass('group-selected').triggerHandler('collapse');

        selected.group = null;
      })

      .children('.group_cap:eq(0)')

        .click(function() {
          $(this).find('.group_title:eq(0)').click();
          return false;
        })

        .children('.group_title:eq(0)')

          .click(function() {
            if (!$group.hasClass('group-selected')) {
              $group.triggerHandler('Select');
            }
            else {
              self.$list.triggerHandler('reset');
            }
            return false;
          });


    this.$groups = (this.$groups == null) ? $group : this.$groups.add($group);
  };


  this.$items = null;

  this.addItem = function(domnode) {
    var $item = $(domnode);

    $item
      .bind('Select', function() {
        if (selected.group) {
          $(selected.group).triggerHandler('deselect');
        }
        else if (selected.item) {
          var $selected_item = $(selected.item);
          $selected_item.triggerHandler('deselect');
          $selected_item.parents('.group:eq(0)').triggerHandler('collapse');
        }

        selected.item = this;

        $(this).addClass('item-selected')
          .parents('.group:eq(0)').triggerHandler('expand');
      })

      .bind('deselect', function() {
        $(this).removeClass('item-selected');
        selected.item = null;
      })

      .click(function() {
        $(this).find('a:eq(0)').click();
        return false;
      })

      .children('a:eq(0)')

        .click(function() {
          $item.triggerHandler('Select');
          return false;
        });


    this.$items = (this.$items == null) ? $item : this.$items.add($item);
  };


  this.$list.find('.group')
    .each(function() {
      self.addGroup(this);
    });

  this.$list.find('.item')
    .each(function() {
      self.addItem(this);
    });

}


// Forms prototype constructor
function SelfCare_Form()
{
  this.DOMConstruct = function(jqselect)
  {
    this.elements = {};

    this.$container = $(jqselect);
    this.$form = this.$container.children('form');

    if (!this.$form.length) {
      return false;
    }

    var elements = this.$form.get(0).elements;
    var i = 0, elem, $elem;
    for (; elem = elements[i]; i++)
    {
      if (!elem.name) {
        continue;
      }

      $elem = $(elem);

      switch (true)
      {
        case $elem.hasClass('input_date'):
          this.elements[elem.name] = new SelfCare_InputDate($elem);
          break;
      
        case $elem.hasClass('input_time'):
          this.elements[elem.name] = new SelfCare_InputTime($elem);
          break;

        case ($elem.attr('type') == 'checkbox' && $elem.hasClass('multicheck')) || $elem.attr('type') == 'radio':
          if (typeof this.elements[elem.name] == 'undefined') {
            this.elements[elem.name] = $(elem);
          } else {
            this.elements[elem.name] = this.elements[elem.name].add(elem);
          }
          break;

        case $elem.parent().hasClass('input_file'):
          this.elements[elem.name] = new SelfCare_InputFile($elem);
          break;

        default:
          this.elements[elem.name] = new SelfCare_Input($elem);
          break;
      }
    }
  };

  this.$input = function(name) {
    return this.elements[name];
  };

  this.show = function(func)
  {
    if (!func) {
      this.$container.show();
    }
    else {
      this.$container.show('fast', func);
    }

    return this;
  };

  this.hide = function(func)
  {
    if (!func) {
      this.$container.hide();
    }
    else {
      this.$container.hide('fast', func);
    }

    return this;
  };

  this.bind = function(type, func) {
    this.$form.bind(type, func);
    return this;
  };

  this.unbind = function(type, func) {
    this.$form.unbind(type, func);
    return this;
  };

  this.submit = function(func) {
    this.$form.submit(func);
    return this;
  };

  var reset_func = null;

  this.reset = function(func)
  {
    this.hide();

    if (reset_func) {
      reset_func();
      reset_func = null;
    }

    this.$form.unbind('submit');

    var name;
    for (name in this.elements) {
      this.elements[name].val('');
    }

    if (func) {
      reset_func = func;
    }

    return this;
  };

}

function SelfCare_setSelectValue(select, value)
{
  var selectedIndex = 0;

  if (value != 0) {
    $.each(select.options,
      function(i, option) {
        if (option.value == value) {
          selectedIndex = i;
          return false;
        }
      });
  }

  select.selectedIndex = selectedIndex;
  $(select).triggerHandler('change');
}


function SelfCare_Input($input)
{
  this.$input = $input;

  if ($input.is('input[type=text]'))
  {
    this.$container = $input.closest('table');

    this.$container.find('.input_text-left')
      .mousedown(function() {
        var $center = $(this).next('.input_text-center');
        $center.children('input:first, select:first').filter(':first').focus();
        return false;
      });

    this.$container.find('.input_text-right')
      .mousedown(function() {
        var $center = $(this).prev('.input_text-center');
        $center.children('input:last').focus();
        return false;
      });

    if (this.$container.hasClass('input_number')) {
      $input.keyfilter(/\d/);
    }

    if ($.browser.msie) {
      $input.keydown(function(e) {
        if (e.keyCode == 13) {
          $input.parents('form').submit();
          return false;
        }
      });
    }
  }
  else if ($input.is('textarea'))
  {
    this.$container = $input.closest('.textarea');

    var $parent = $input.parent();
    $parent.css({width: $parent.width(), height: $parent.height()});

    var width = this.$container.width();
    var height = this.$container.height();

    $input.css({
      position: 'absolute',
      top: 0,
      left: 0,
      width: width - 10,
      height: height - 2
    });
  }
  else if ($input.is('select'))
  {
    this.$container = $input.closest('table');

    if ($input.children(':first').hasClass('empty'))
    {
      var change = function()
      {
        var $this = $(this);

        if (this.selectedIndex == 0 && !$this.hasClass('empty')) {
          $this.addClass('empty');
        }
        else if (this.selectedIndex != 0 && $this.hasClass('empty')) {
          $this.removeClass('empty');
        }
      };

      $input
        .bind('change', change)
        .bind('click', change)
        .bind('keyup', change);

      $input.triggerHandler('change');
    }
  }
}

SelfCare_Input.prototype =
{
  setOnEmptyValueLabel: function(label)
  {
    this.$input
      .focus(function() {
        var $this = $(this);
        if ($this.hasClass('input_text-empty')) {
          $this.val('').removeClass('input_text-empty');
        }
      })
      .blur(function() {
        var $this = $(this);
        if (!$this.val()) {
          $this.addClass('input_text-empty').val(label);
        }
      });

    this.val = function(value)
    {
      if (typeof value == 'undefined') {
        return !this.$input.hasClass('input_text-empty') ? this.$input.val() : '';
      }

      if (value) {
        this.$input.removeClass('input_text-empty');
      }

      SelfCare_Input.prototype.val.call(this, value);

      this.$input.triggerHandler('blur');
    };

    this.$input.triggerHandler('blur');
  },

  val: function(value)
  {
    if (typeof value == 'undefined') {
      return this.$input.val();
    }
    else {
      this.$input.val(value);
      return this;
    }
  },

  attr: function(a, v)
  {
    if (v === undefined) {
      return this.$input.attr(a);
    }
    else {
      this.$input.attr(a, v);
      return this;
    }
  },

  removeAttr: function(a) {
    this.$input.removeAttr(a);
    return this;
  },

  focus: function() {
    this.$input.focus();
    return this;
  },

  select: function() {
    this.$input.select();
    return this;
  },

  blur: function() {
    this.$input.blur();
    return this;
  },

  show: function() {
    this.$container.show();
  },

  hide: function() {
    this.$container.hide();
  },

  bind: function(a, b, c) {
    this.$input.bind(a, b, c);
    return this;
  }
};


function SelfCare_CreateInput(attrs)
{
  var $table = $(SelfCare_CreateInput.html);

  $('<input/>').attr(attrs)
    .appendTo($table.find('.input_text-center'));

  return $table;
}
SelfCare_CreateInput.html = '<table cellspacing="0" class="input_text"><tbody><tr><td class="input_text-left"/><td class="input_text-center"/><td class="input_text-right"/></tr></tbody></table>';

function SelfCare_CreateButton(value, type)
{
  type = type || 'button';

  var $table = $(SelfCare_CreateButton.html);

  $('<input type="' + type + '"/>').val(value)
    .appendTo($table.find('.input_button-center'));

  return $table;
}
SelfCare_CreateButton.html = '<table cellspacing="0" class="input_button"><tbody><tr><td class="input_button-left"/><td class="input_button-center"/><td class="input_button-right"/></tr></tbody></table>';


var SelfCare_datetime_parser = /^(\d{2})\.(\d{2})\.(\d{4})\s(\d{2}):(\d{2}):(\d{2})$/;
var SelfCare_date_format_regex = /^((\d{1,2})\.(\d{1,2})\.(\d{2,4}))(?:\s|$)/;
var SelfCare_calendar_date_format = 'dd.MM.yyyy';

function getCalendarObject()
{
  if (!$('#singleton_calendar_host').length)
  {
    $('body').append(
      '<div id="singleton_calendar_host" style="display: none;">' +
        '<div id="singleton_calendar" name="singleton_calendar"/>' +
      '</div>' +
      '<a href="#" id="singleton_calendar_button" name="singleton_calendar_button"></a>'
    );

    var calendar = CalendarPopup('singleton_calendar');
    calendar.setDayHeaders('Вс','Пн','Вт','Ср','Чт','Пт','Сб');
    calendar.setMonthNames('Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь');
    calendar.setTodayText('Сегодня');
    calendar.setWeekStartDay(1);
    calendar.showNavigationDropdowns();
    calendar.setReturnFunction('SelfCare_InputDate_pickDate');
    calendar.copyMonthNamesToWindow();

    window.SelfCare_CalendarObject = calendar;
  }

  return window.SelfCare_CalendarObject;
}

function SelfCare_InputDate_pickDate(y, m, d)
{
  var calendar = getCalendarObject();

  var value = formatDate(new Date(y, m-1, d, 0, 0, 0), SelfCare_calendar_date_format);

  if (SelfCare_datetime_parser.test(calendar.$input.val()))
  {
    if (/start/i.test(calendar.$input.attr('name'))) {
      value += ' 00:00:00';
    }
    else if (/end/i.test(calendar.$input.attr('name'))) {
      value += ' 23:59:59';
    }
  }

  calendar.$input.val(value);
}


function SelfCare_InputDate($input)
{
  SelfCare_Input.call(this, $input);

  $input.closest('table').find('.date_picker_btn')
    .click(function()
    {
      var calendar = getCalendarObject();

      calendar.$input = $(this).closest('table').find('input');

	    var value = $.trim(calendar.$input.val());
	    if (SelfCare_date_format_regex.test(value)) {
	      var date = SelfCare_date_format_regex.exec(value)[1];
		    calendar.currentDate = new Date(getDateFromFormat(date, SelfCare_calendar_date_format));
		  } else {
		    calendar.currentDate = new Date();
		  }

	    calendar.populate(calendar.getCalendar());

	    if (!calendar.populated) {
		    calendar.populated = true;
		    calendar.refresh();
		  }

		  calendar.showPopup('singleton_calendar_button');

		  $('#singleton_calendar')
		    .css({top: 'auto', left: 'auto'});

		  $('#singleton_calendar_host')
		    .appendTo(
		      $(this).next('.calendar_host')
		    ).show();

		  $(this).next('.calendar_host')
		    .unbind('click')
		    .bind('click', function(event) {
		      if (!$(event.target).is('a')) {
		        return false;
		      }
		    })
		    .show();

		  $(document).one('click', function() {
		    $('.calendar_host').hide();
        $('#singleton_calendar_host').hide().appendTo('body');
		  });

      return false;
    });

}
SelfCare_InputDate.prototype = SelfCare_Input.prototype;


function SelfCare_InputTime($input)
{
  SelfCare_Input.call(this, $input);

  var $inputs = $input.siblings('input.input_time_item');

  var normalize_val = function(input, offset)
  {
    offset = offset || 0;

    var $input = $(input);

    var value = input.value;
    var number = parseInt(value, 10);
    if (isNaN(number)) {
      number = 0;
    } else {
      number += offset;
    }

    if ($input.hasClass('input_hours'))
    {
      if (number < 0) {
        input.value = offset ? '23' : '0';
      }
      else if (number > 23) {
        input.value = offset ? '0' : '23';
      }
      else {
        input.value = number.toString();
      }
    }
    else if ($input.hasClass('input_minutes') || $input.hasClass('input_seconds'))
    {
      if (number < 0) {
        if (offset) {
          normalize_val($input.prev('.input_time_item').get(0), -1);
          input.value = '59';
        }
        else {
          input.value = '00';
        }
      }
      else if (number > 59) {
        if (offset) {
          normalize_val($input.prev('.input_time_item').get(0), 1);
          input.value = '00';
        }
        else {
          input.value = '59';
        }
      }
      else {
        value = number.toString();
        input.value = (number > 9) ? value : ('0' + value);
      }
    }
  };

  $inputs
    .keydown(function(event)
    {
      if (event.keyCode == 38) { // up arrow
        normalize_val(this, 1);
      }
      else if (event.keyCode == 40) { // down arrow
        normalize_val(this, -1);
      }
    })
    .blur(function() {
      normalize_val(this);
    })
    .each(function() {
      normalize_val(this);
    });

}
SelfCare_InputTime.prototype = SelfCare_Input.prototype;


function SelfCare_InputFile($input)
{
  this.$input = $input;
  this.$iframe = $input.parent().children('iframe');

  this.contentWindow = this.$iframe.get(0).contentWindow;


  var callback_func;

  this.onFileUpload = function(func) {
    callback_func = func;
  };

  this.contentWindow.onFileUpload = function() {
    callback_func.call(this, arguments);
  };
}
SelfCare_InputFile.prototype = SelfCare_Input.prototype;


function SelfCare_NetworkEventsViewForm(type_selector_name)
{
  this.DOMConstruct('#network_events_viewer_form');
  var form = this;

  this.submit(function()
  {
    var start_val = form.$input('StartDate').val(),
        end_val = form.$input('EndDate').val(),
        start_a = SelfCare_date_format_regex.exec(start_val),
        end_a = SelfCare_date_format_regex.exec(end_val);

    if (!start_a || !end_a)
    {
      alert('Неверный формат даты');
      if (!start_a) {
        form.$input('StartDate').focus().select();
      }
      else if (!end_a) {
        form.$input('EndDate').focus().select();
      }
      return false;
    }

    var start_time = (new Date(start_a[4], start_a[3] - 1, start_a[2], 0, 0, 0)).getTime(),
        end_time = (new Date(end_a[4], end_a[3] - 1, end_a[2], 23, 59, 59)).getTime();

    if (start_time >= end_time) {
      alert('Неверно задан временной интервал');
      form.$input('EndDate').focus().select();
      return false;
    }

    var max_range_time = (14 * (24 * 60 * 60)) * 1000;

    if ((end_time - start_time) > max_range_time) {
      alert('Просмотр статистики возможен только за период не более двух недель');
      form.$input('EndDate').focus().select();
      return false;
    }

    var params = {
      user_input_1: 'content',
      user_input_3: start_val,
      user_input_4: end_val
    };

    form.$input(type_selector_name)
      .each(function() {
        params['user_input_multi_2_' + this.value] = this.checked ? 'true' : '';
      });

    SelfCare.request('_next', params);

    return false;
  });
}
SelfCare_NetworkEventsViewForm.prototype = new SelfCare_Form;


// Main Menu functionality
function SelfCare_MainMenu()
{
  var self = this;

  var opened_main, opened_sub;
  
  this.setActiveTab = function(main, sub) {
    opened_main = main;
    opened_sub = sub;
    this.hide_sub();
  };

  var all_out = function() {
    $('#main_menu > .lvl2:visible').hide();
    $('#main_menu > .lvl1 > li > a')
      .attr('class', 'center1');
  };

  this.hide_sub = function()
  {
    all_out();

    if (opened_main) {
      this.main_menu_item_over($('#main_a_' + opened_main).get(0), opened_main);
      this.main_submenu_item_over($('#sub_a_' + opened_main + '_' + opened_sub).get(0), opened_sub);
    }
  };

  var hideTimer = null;

  var startTimer = function() {
    if (hideTimer) {
      clearTimeout(hideTimer);
    }

    hideTimer = setTimeout(function() { self.hide_sub(); }, 2000);
  };

  var stopTimer = function() {
    if (hideTimer) {
      clearTimeout(hideTimer);
      hideTimer = null;
    }
  };

  this.main_menu_over = function() {
    stopTimer();
  };

  this.main_menu_out = function() {
    startTimer();
  };

  this.main_menu_item_over = function(obj, sub_n)
  {
    if (typeof obj == 'undefined') { return; }
    all_out();
    $('#sub_main_' + sub_n).show();
    obj.className = 'center1 menua';
  };

  this.main_submenu_item_over = function(obj)
  {
    var i = 1;
    while ($('#sub_main_'+i).length) {
      var j = 1;
      while ($('#sub_a_'+i+'_'+j).length) {
        $('#sub_a_'+i+'_'+j).attr('class', 'center2');
        j++;
      }
      i++;
    }

    try {
      obj.className = 'center2 menua2';
    }
    catch (ex) { }
  };
}

// Main menu singleton instance
var SelfCare_mainmenu;

// Main menu html handlers
function main_menu_over() {
  try {
    SelfCare_mainmenu.main_menu_over();
  } catch(e) { }
}

function main_menu_out() {
  try {
    SelfCare_mainmenu.main_menu_out();
  } catch(e) { }
}

function main_menu_item_over(obj, sub_n) {
  try {
    SelfCare_mainmenu.main_menu_item_over(obj, sub_n);
  } catch(e) { }
}

function main_submenu_item_over(obj) {
  try {
    SelfCare_mainmenu.main_submenu_item_over(obj);
  } catch(e) { }
}

function main_submenu_item_click(nav_path, opened_main, opened_sub)
{
  main_menu_set_active_tab(opened_main, opened_sub);

  SelfCare.request(nav_path, [], 'content');
  
  PrevImageOff();
  StopMelody();
  
  return false;
}

function main_menu_set_active_tab(opened_main, opened_sub)
{
  if (!SelfCare_mainmenu) {
    SelfCare_mainmenu = new SelfCare_MainMenu;
  }

  SelfCare_mainmenu.setActiveTab(opened_main, opened_sub);
}



// [GateWay (Role Select)]
function SelfCare_Gateway()
{
  var self = this;

  /* simple subscriber button */
  $("#subscriber_choose_icon, #subscriber_choose_label")
    .click(function() { self.selectRole('1'); return false; });


  /* corporate client button */
  $("#client_choose_icon, #client_choose_label")
    .click(function() { self.selectRole('2'); return false; });
  

  /* dealer button (protocol conditional) */
  var $img = $('<img id="gateway_img" width="679" height="498"/>');

  if (window.location.protocol != "https:") {
    $img.attr("src", url_Images + "gateway.png");
  }
  else {
    $img.attr("src", url_Images + "gateway-https.png");
    
    $("#dealer_choose_icon, #dealer_choose_label")
      .attr("href", "?use=2.0#role-id=3")
      .removeAttr("onclick")
      .removeClass("disabled");
  }
  
  $("#gateway").prepend($img[0]);


  /* content provide button */
  $("#provider_choose_icon, #provider_choose_label")
      .attr("href", "?use=2.0#role-id=4")
      .removeAttr("onclick")
      .removeClass("disabled");

  
  /* animating apperiance */
  window.setTimeout(function() {
    $("#gateway a:not(.disabled)").hover(
        function() { $(this).fadeTo(250, 0); },
        function() { $(this).fadeTo(750, 0.3); }
    );

    $("#gateway a").fadeTo(1500, 0.3);
  }, 100);
}
SelfCare_Gateway.prototype = {
  selectRole: function(role_id) {
    SelfCare.request("_next", [role_id]);
  }
};


// [ Authentication ]
function SelfCare_SubscriberAuthentication()
{
  var self = this;

  $('#get_password_button')
    .click(function() {
      var role_id = /get_password_for_role-(\d+)/.exec(this.className)[1];
      self.openRegistrationIFrame(role_id);
      return false;
    });

  var card_type_id = $('#CardTypeId').text(),
      $login, $passwd, $inputs_host;

  switch (card_type_id)
  {
    case '4':
        $inputs_host = $('#subscriber_auth_inputs');
        $login = $inputs_host.children('input[name=auth_msisdn]');
        $passwd = $inputs_host.children('input[name=password]');
      break;

    case '11':
        $inputs_host = $('#client_auth_inputs');
        $login = $inputs_host.children('input[name=auth_contract]');
        $passwd = $inputs_host.children('input[name=password]');
      break;

    default:
      throw 'Unknown card type id "' + card_type_id + '"';
      break;
  }

  $login.appendTo('#auth_login_container');
  $passwd.appendTo('#auth_password_container');

  $('#exit_button').one('click', function() {
    $login.add($passwd).appendTo($inputs_host);
    SelfCare.request('_back');
    return false;
  });
  
  $('#authentication_form > form')
    .submit(function()
    {
      var login_val = $.trim($login.val());
      if (!login_val.length) {
        $login.val('').focus();
        return false;
      }

      var passwd_val = $.trim($passwd.val());
      if (!passwd_val.length) {
        $passwd.val('').focus();
        return false;
      }

      SelfCare.request(
        '_next', [login_val, passwd_val],
        'Authentication',
        function(status, $response)
        {
          if (status != 'success') { return; }

          if ($response.children('#AuthenticationStatus').text() == 'failed') {
            $login.focus().select();
          }
          else {
            $login.add($passwd).appendTo($inputs_host);
          }
        });

      return false;
    });
  
  $login.focus();
}
SelfCare_SubscriberAuthentication.prototype =
{
  $iframe: null,

  openRegistrationIFrame: function(CardTypeId)
  {
    var self = this;

    if (!this.$iframe) {
      // creating iframe on the fly
      this.$iframe = $('<iframe scrolling="no" frameborder="0"/>')
          .attr('src', url_RegistrationModule + '?CARD_TYPE_ID=' + CardTypeId)
          .css({width: 275, height: 200})
          .appendTo('#get_password_form > .iframe_container');
    }

    var content_height = 330;

    if (CardTypeId != 4) {
      $('#get_password_form > p').hide();
      content_height = 280;
    }

    window.PageShader
      .show('#get_password_form', 300, content_height)
      .onhide(function() {
        self.$iframe.remove();
        self.$iframe = null;
      });
  }
};


// [Base Profile] static class.
var BaseProfile = {
  deviceDefaultImage: null,

  changePhoneModel: function() {
    var $button = $("#change_device_button");
    if ($button.hasClass("disabled")) {
      return;
    }
    $button.addClass("disabled");

    // setting current image uri as default
    BaseProfile.deviceDefaultImage = $("#device_info_image > img").attr("src");

    SelfCare.request(
      "_next", ['1'], "content",
      function(status, $response) {
        if (status != "success") {
          $button.removeClass("diabled");
          return;
        }
        
        $("#device_undetected").hide();
        
        // gathering select nodes
        var $content = $response.children("#contentbody"),
            $brand_select_container = $content.children("#select_device_brand"),
            $model_select_container = $content.children("#select_device_model"),
            $brand_select = $brand_select_container.find("select"),
            $model_select = $model_select_container.find("select"),
            brandSelectedIndex = $brand_select[0].selectedIndex,
            modelSelectedIndex = $model_select[0].selectedIndex;
        
        // device brand select init
        var brandSelectChange = function() {
            window.setTimeout(function() {
              if ($brand_select[0].selectedIndex == brandSelectedIndex) {
                return; // not changed
              }
              brandSelectedIndex = $brand_select[0].selectedIndex;

              $brand_select.attr("disabled", true);
              $model_select.empty();

              SelfCare.request("_next",
                [$brand_select[0].value, $model_select[0].value, '1'],
                "brand-change",
                function(status, $response) {
                  $brand_select.attr("disabled", false);
                  
                  if (status != "success") {
                    alert("Ошибка выполнения операции");
                    return;
                  }

                  var $content = $response.children("#contentbody");
                  var $model_select_options = $content.find("#select_device_model select").children();
                  
                  $model_select.append($model_select_options);
                  modelSelectedIndex = $model_select[0].selectedIndex = 0;
                  
                  BaseProfile.updateDeviceImage();
                  
                }, true);

            }, 10);
          };
        
        $brand_select.bind("change", brandSelectChange)
            .bind("click", brandSelectChange)
            .bind("keyup", brandSelectChange);
        
        $("#device_info_brand")
            .find("> .value")
              .hide()
              .end()
            .append($brand_select_container[0]);
        
        
        // device model select detection
        var modelSelectChange = function() {
            window.setTimeout(function() {
              if ($model_select[0].selectedIndex == modelSelectedIndex) {
                return; // not changed
              }
              modelSelectedIndex = $model_select[0].selectedIndex;

              BaseProfile.updateDeviceImage();

            }, 10);
          };

        $model_select.bind("change", modelSelectChange)
            .bind("click", modelSelectChange)
            .bind("keyup", modelSelectChange);

        $("#device_info_model")
            .find("> .value")
              .hide()
              .end()
            .append($model_select_container[0]);

        
        // device select controls
        $button.hide()
            .before($content.children("#change_device_controls"));

        $brand_select_container
            .closest(".profile_info").show();

      }, true);
  },

  updateDeviceImage: function() {
    $("#image_not_found_message").hide();

    var $deviceBrandSelect = $("#select_device_brand select"),
        deviceBrandName = $deviceBrandSelect.children().eq($deviceBrandSelect[0].selectedIndex).text();

    var $deviceModelSelect = $("#select_device_model select"),
        deviceModelName = $deviceModelSelect.children().eq($deviceModelSelect[0].selectedIndex).text();

    var deviceFullName = deviceBrandName + " " + deviceModelName;
    var deviceImageFileName = encodeURIComponent(deviceBrandName + "-" + deviceModelName.replace(":", "_"));

    $("#device_info_image > img")
        .attr({
          title: deviceFullName,
          src: "/WebSelfCare/download.file?storage=003&param1=" + deviceImageFileName + ".png"
        })
        .show();
  },

  onImageNotFound: function() {
    $("#image_not_found_message").show();
    $("#device_info_image > img").hide();
  },
  
  hideDeviceSelectForm: function() {
    $("#change_device_controls")
        .remove();

    var $deviceBrandSelect = $("#select_device_brand"),
        deviceBrandCurrentValue = $.trim($deviceBrandSelect.siblings(".value").text());

    if (deviceBrandCurrentValue.length == 0) {
      $deviceBrandSelect.closest(".profile_info").hide();
      $("#device_undetected").show();
    }

    $deviceBrandSelect
        .siblings(".value")
          .show()
          .end()
        .remove();
    
    $("#select_device_model")
        .siblings(".value")
          .show()
          .end()
        .remove();

    // returning default image uri
    $("#device_info_image > img")
        .attr("src", BaseProfile.deviceDefaultImage);
    
    $("#change_device_button")
        .removeClass("disabled")
        .show();
    
    SelfCare.request("_root/1/1", [], "content", function() {}, true);
  },
  
  updateDeviceInformation: function() {
    var $brand_select = $("#select_device_brand select"),
        $model_select = $("#select_device_model select");
    
    SelfCare.request("_next",
      [$brand_select[0].value, $model_select[0].value, '2'],
      "content",
      function(status, $response) {
        if (status != "success") {
          return;
        }
        
        SelfCare.loadResponse($response, "content");
        
      }, true);
  }
};



// [Service Profile]
function SelfCare_MSISDNForm(container_select)
{
  this.DOMConstruct(container_select);

  var $msisdn = this.$input('msisdn');

  if ($msisdn) {
    this.$input('msisdn').setOnEmptyValueLabel('Номер');
  }
}
SelfCare_MSISDNForm.prototype = new SelfCare_Form;


function SelfCare_TimerSetupForm(container_select)
{
  this.DOMConstruct(container_select);

  this.interval_id = null;

  var form = this;

  var holdtimer = null;

  var setValues = function(days, hours, minutes)
  {
    if (!holdtimer) {
      form.$input('days').val(days);
      form.$input('hours').val(hours);
      form.$input('minutes').val(minutes);
    }
  };

  this.setupTimer = function(datetime)
  {
    if (datetime == '31.12.2999 00:00:00') {
      this.$container.prev('.service_end_date').text('действует до момента ручного отключения');
    }
    else {
      this.$container.prev('.service_end_date').text('действует до ' + datetime);

      var tmp = SelfCare_datetime_parser.exec(datetime);
      var end_dt = new Date(tmp[3], (tmp[2] - 1), tmp[1], tmp[4], tmp[5], tmp[6]);

      var int_dt = new Date(end_dt.getTime() - (new Date()).getTime());
      setValues(int_dt.getUTCDate() - 1, int_dt.getUTCHours(), int_dt.getUTCMinutes());

      if (!this.interval_id)
      {
        this.interval_id =
          setInterval(function()
          {
            int_dt = new Date(end_dt.getTime() - (new Date()).getTime());

            if (int_dt.getTime() > 0) {
              setValues(int_dt.getUTCDate() - 1, int_dt.getUTCHours(), int_dt.getUTCMinutes());
            }
            else {
              form.resetTimer();
              SelfCare.request('_root/1/2', [], 'content');
            }
          }, 1000);
      }
    }
  };

  this.stopTimer = function()
  {
    if (this.interval_id) {
      clearInterval(this.interval_id);
      this.interval_id = null;
    }
  };

  this.$container
    .unload(function() {
      form.stopTimer();
    });
  
  this.resetTimer = function()
  {
    this.stopTimer();
    this.$container.prev('.service_end_date').text('');
    setValues('0', '0', '0');
  };


  var hold_milliseconds = 10000; // 10 sec

  var holdTimerRefreshing = function()
  {
    if (holdtimer) {
      clearTimeout(holdtimer);
    }

    holdtimer = setTimeout(function() {
      holdtimer = null;
    }, hold_milliseconds);
  };

  this.$input('days').$input.mousedown(holdTimerRefreshing).focus(holdTimerRefreshing);
  this.$input('hours').$input.mousedown(holdTimerRefreshing).focus(holdTimerRefreshing);
  this.$input('minutes').$input.mousedown(holdTimerRefreshing).focus(holdTimerRefreshing);
}
SelfCare_TimerSetupForm.prototype = new SelfCare_Form;


function SelfCare_CountrySelectForm() {
  this.DOMConstruct('#select_country_container');
}
SelfCare_CountrySelectForm.prototype = new SelfCare_Form;


function SelfCare_ServiceProfile()
{
  var ServiceProfile = this;

  var $menu_lvl1_hover = $('#view_contacts'),
      $menu_lvl1_active = $menu_lvl1_hover;

  var $menu_lvl2_hover = null, $menu_lvl2_active = null;

  var timeout = null;

  var startTimeout = function()
  {
    if (timeout) {
      clearTimeout(timeout);
    }

    timeout = setTimeout(function() {
      $menu_lvl1_active.triggerHandler('mouseover');
      if ($menu_lvl2_active) {
        $menu_lvl2_active.triggerHandler('mouseover');
      }
    }, 2000);
  };

  var resetTimeout = function() {
    if (timeout) {
      clearTimeout(timeout);
      timeout = null;
    }
  };

  $('#contact_list_controls')
    .hover(
      function() { resetTimeout(); },
      function() { startTimeout(); }
    );

  $('#contact_list_controls > a')
    .mouseover(function() {
      if ($(this).hasClass('btn-disabled') || this.id == $menu_lvl1_hover.attr('id')) { return; }

      $menu_lvl1_hover.removeClass('btn-active');

      $('#' + $menu_lvl1_hover.attr('id') + '_status').hide();

      $menu_lvl1_hover = $(this).addClass('btn-active');
      $('#' + this.id + '_status').show();
    })
    .bind('activate', function() {
      var $prev_active_item = $menu_lvl1_active;

      $menu_lvl1_active = $(this);
      $menu_lvl1_active.triggerHandler('mouseover');

      $('#' + $prev_active_item.attr('id') + '_status')
        .find('.btn-active').removeClass('btn-active');
    })
    .click(function() { return false; });

  $('#add_functions_status > a, #delete_functions_status > a')
    .mouseover(function() {
      if ($(this).hasClass('btn-disabled') || ($menu_lvl2_hover && this.id == $menu_lvl2_hover.attr('id'))) { return; }

      if ($menu_lvl2_hover) {
        $menu_lvl2_hover.removeClass('btn-active');
      }

      $menu_lvl2_hover = $(this).addClass('btn-active');
    })
    .bind('activate', function() {
      $menu_lvl2_active = $(this);
      $menu_lvl2_active.triggerHandler('mouseover');
    });

  /* View contacts status handling */
  var $view_contacts_status = $('#view_contacts_status');

  this.setViewContactStatus = function(item_number) {
    $('#view_contacts').triggerHandler('activate');
    $view_contacts_status.children('.btn-active').removeClass('btn-active');
    $view_contacts_status.children('a:eq(' + (item_number - 1) + ')').addClass('btn-active');
  };

  var anumber_list_type_parser = /(?:^|\s)(\w+)_list_item(?:$|\s)/i;

  var recognizeANumberEntry = function(dom_node)
  {
    var $dom_node = $(dom_node);

    return {
      msisdn: $.trim($dom_node.find('.phone_num').text()).substr(1),
      list_type: anumber_list_type_parser.exec(dom_node.className)[1]
    };
  };

  var selected = {
    msisdn: null,
    list_type: null
  };

  var ContactList = new GroupedListControl('#service_contact_list');

  var ContactListItemSelectDelegate = function()
  {
    ServiceProfile.cancelActiveAction();

    selected = recognizeANumberEntry(this);

    if (selected.list_type == 'white') {
      ServiceProfile.setViewContactStatus(1);
      $('#delete_from_black_list').addClass('btn-disabled');
      $('#delete_from_white_list').removeClass('btn-disabled');
    }
    else if (selected.list_type == 'black') {
      $('#delete_from_white_list').addClass('btn-disabled');
      $('#delete_from_black_list').removeClass('btn-disabled');
      ServiceProfile.setViewContactStatus(2);
    }

    $('#delete_functions').removeClass('btn-disabled');
  };

  if (ContactList.$items) {
    ContactList.$items.bind('Select', ContactListItemSelectDelegate);
  }

  ContactList.$list
    .bind('reset', function()
    {
      $('#delete_functions, #delete_from_white_list, #delete_from_black_list').addClass('btn-disabled');

      selected.msisdn = null;
      selected.list_type = null;
    });


  var clicked = function(btn)
  {
    var $btn = $(btn);

    $btn.siblings('.btn-active').removeClass('btn-active');

    var parent_id = $btn.parent().attr('id');
    var anchor_id = parent_id.replace(/_status$/, '');
    $('#' + anchor_id).triggerHandler('activate');

    $btn.triggerHandler('activate');
    $btn.focus();
  };


  var EditMSISDNForm = new SelfCare_MSISDNForm('#edit_msisdn_form');

  this.cancelActiveAction = function() {
    EditMSISDNForm.reset();
  };

  var add_msisdn_handler = function(event)
  {
    if ($(this).hasClass('btn-disabled')) {
      return false;
    }
    
    var list_type = event.data.list_type;

    ServiceProfile.cancelActiveAction();
    ContactList.$list.triggerHandler('reset');

    $('#' + list_type + '_list')
      .append(EditMSISDNForm.$container);

    EditMSISDNForm
      .submit(function()
      {
        var $msisdn = EditMSISDNForm.$input('msisdn');
        var phone_num = $.trim($msisdn.val());

        if (!phone_num.length) {
          $msisdn.focus().select();
          return false;
        }
        else if (!/^(?:\+|0{1,2})[1-9]\d+$/.test(phone_num))
        {
          alert('Неверный формат телефонного номера');
          $msisdn.val(phone_num);
          $msisdn.focus().select();
          return false;
        }

        if (phone_num[0] == '0')
        {
          if (phone_num[1] == '0') {
            phone_num = '+' + phone_num.substr(2);
          }
          else {
            phone_num = '+996' + phone_num.substr(1);
          }
        }

        EditMSISDNForm.reset();

        ServiceProfile.sendAddMSISDN(list_type, phone_num);

        return false;
      });

    EditMSISDNForm.show();

    clicked(this);

    $(this).blur();
    EditMSISDNForm.$input('msisdn').focus();

    return false;
  };

  $('#add_into_white_list')
    .bind('click', {list_type: 'white'}, add_msisdn_handler);

  $('#add_into_black_list')
    .bind('click', {list_type: 'black'}, add_msisdn_handler);

  var list_type_text = {white: 'белого', black: 'чёрного'};

  var delete_anumber_handler = function(event)
  {
    var $this = $(this);

    if ($this.hasClass('btn-disabled')) {
      $this.blur();
      return false;
    }

    ServiceProfile.cancelActiveAction();

    var list_type = event.data.list_type;

    if (window.confirm(
      'Вы действительно хотите удалить номер "'+selected.msisdn+'" из '+list_type_text[list_type]+' списка?'
    )) {
      var msisdn = selected.msisdn;

      var selected_item = ContactList.getSelectedItem();
      ContactList.$list.triggerHandler('reset');
      $(selected_item).remove();

      ServiceProfile.sendDeleteMSISDN(list_type, msisdn);
    }

    return false;
  };

  $('#delete_from_white_list')
    .bind('click', {list_type: 'white'}, delete_anumber_handler);

  $('#delete_from_black_list')
    .bind('click', {list_type: 'black'}, delete_anumber_handler);


  this.sendRequest = function(service_id, operation_id, params, context, oncomplete)
  {
    var query = '_cancel/' + context + '/' + service_id + '/' + operation_id;

    if (params.length) {
      query += '/' + params.join('/');
    }

    SelfCare.request(query, null, oncomplete);
  };

  var list_type_id_dict = {white: 11, black: 27};

  this.sendAddMSISDN = function(list_type, msisdn)
  {
    this.sendRequest(
      list_type_id_dict[list_type], 2, [msisdn],
      'AddMSISDN?list_type=' + list_type,
      function(status, $response) {
        if (status != 'success') { return false; }

        var $operation_status = $response.children('#OperationStatus');
        if (!$operation_status.length || $operation_status.text() != 'success') {
          return false;
        }

        var $updated_ul = $response.find('#UpdatedList > ul');
        var list_id = $updated_ul.attr('id');
        var $current_ul = $('#' + list_id);

        $current_ul.children('.empty').remove();

        $updated_ul.children('li')
          .each(function() {
            var $this = $(this);
            var phone_num = $this.find('.phone_num').text();
            if (!$current_ul.children("li:contains('" + phone_num + "')").length) {
              $current_ul.append(this);
              ContactList.addItem(this);
              $this.bind('Select', ContactListItemSelectDelegate);
              return false;
            }
          });

      });
  };

  this.sendDeleteMSISDN = function(list_type, msisdn)
  {
    this.sendRequest(
      list_type_id_dict[list_type], 3, [msisdn],
      'DeleteMSISDN?list_type=' + list_type,
      function(status, $response) {
        if (status != 'success') { return false; }

        var $operation_status = $response.children('#OperationStatus');
        if (!$operation_status.length || $operation_status.text() != 'success') {
          return false;
        }

        var $current_list = $('#' + list_type + '_list');
        var $current_items = $current_list.children('li:not(#edit_msisdn_form)');
        if (!$current_items.length) {
          $current_list.append('<li class="empty">cписок пуст</li>');
        }
      }
    );
  };


  var CountrySelectForm = new SelfCare_CountrySelectForm;

  var $country_select = CountrySelectForm.$input('country_id');
  var active_country_id = $country_select.val();

  CountrySelectForm.submit(function()
  {
    var selected_country_id = $country_select.val();

    if (selected_country_id == '') {
      alert('Выберите страну');
      $country_select.focus();
    }
    else if (selected_country_id == active_country_id) {
      alert('Нельзя выбрать ту же страну');
      $country_select.focus();
    }
    else {
      ServiceProfile.sendRequest(3, 4, [selected_country_id], 'FavoriteCountrySelect');
    }

    return false;
  });
  
  var service_id_parser = /^service-(\d+)$/;

  var getServiceStatus = function($service) {
    return $service.find('.service_status > span').hasClass('service_status-on') ? 1 : 0;
  };

  var ServiceTitleClick = function()
  {
    var $service = $(this).closest('.service');
    var service_id = service_id_parser.exec($service.attr('id'))[1];

    var $info_div = $service.children('.service_info');
    var $desc_div = $service.children('.service_description');

    if (!$desc_div.length)
    {
      $desc_div = $('<div class="service_description"/>')
        .append('<p class="loading">Загрузка...</p>');

      $info_div.hide();
      $service.addClass('text_block-expanded');
      $info_div.after($desc_div);

      $.ajax({
        url: url_ServiceInfoDir + 'service-' + service_id + '.xml',
        dataType: 'html',

        success: function(html) {
          $desc_div
            .empty().removeClass('loading')
            .append(
              $(html).filter('#htmlpart').children()
            );
        }
      });
    }
    else if ($desc_div.is(':visible')) {
      $desc_div.hide();
      $service.removeClass('text_block-expanded');
      $info_div.show();
    }
    else {
      $info_div.hide();
      $service.addClass('text_block-expanded');
      $desc_div.show();
    }

    return false;
  };


  var StatusToggleButtonValues = ['Подключить', 'Отключить'];

  var StatusToggleButtonClick = function()
  {
    var $button = $(this);
    var $service = $button.closest('.service');

    if ($service.hasClass('locked')) {
      return false;
    }
    $service.addClass('locked');

    var service_id = service_id_parser.exec($service.attr('id'))[1];
    var curr_status = getServiceStatus($service);

    var operation_id = (curr_status ? '0' : '1');

    var context;
    if (service_id == '11' || service_id == '27') { context = 'content'; }
    else if (service_id == '18') { context = 'page'; }
    else { context = 'ServiceStatusToggle?service_id=' + service_id; }

    ServiceProfile
      .sendRequest(service_id, operation_id, [],
        context, function(status, $response)
        {
          if (status != 'success') { return; }
          
          var $content = $('#right_content');
          var $serviceupdate_list = $response.find('#ServiceUpdates > .ServiceUpdate');

          $serviceupdate_list
            .each(function(i, serviceupdate) {
              var $serviceupdate = $(serviceupdate);
              $('#service-' + $serviceupdate.attr('id')).appendTo($content);
            });

          var $update_subject = $serviceupdate_list.filter('#' + service_id),
              subscribtion_id = $update_subject.children('.SubscribtionID').text(),
              start_date = $update_subject.children('.StartDate').text(),
              //end_date = $update_subject.children('.EndDate').text(),
              service_enabled = (subscribtion_id != '-1');

          var status_label = service_enabled ? 'подключен с ' + start_date : 'не подключен';
          
          $service.children('.service_status').children('span')
              .attr('class', 'service_status-' + (service_enabled ? 'on' : 'off'))
              .children('.text').text(status_label);

          $button.val(StatusToggleButtonValues[(service_enabled ? 1 : 0)]);

          var $custom_controls = $service.find('.service_controls > .custom_controls');
          if ($custom_controls.length)
          {
            if (service_id == '40' && service_enabled) { // DoNotDisturb
              $custom_controls.children('.service_end_date').text('действует до момента ручного отключения');
            }
            
            if (service_enabled) {
              $custom_controls.show();
            } else {
              $custom_controls.hide();
            }
          }

          $service.removeClass('locked');
          
          $('#service-' + service_id).intoViewport({duration: 'normal', easing: 'swing'});
        });

    return false;
  };


  $('#right_content > .service')
    .each(function()
    {
      var $service = $(this);

      $service.children('.text_block_header').click(ServiceTitleClick);

      var $status_toggle = new SelfCare_CreateButton(StatusToggleButtonValues[getServiceStatus($service)], 'button').addClass('status_toggle');
      $status_toggle.find('input[type=button]').click(StatusToggleButtonClick);

      $service.children('.service_controls')
        .append($status_toggle)
        .append('<div class="clear"/>');
    });


  this.DNDTimer = new SelfCare_TimerSetupForm('#dnd_timer_setup_form');

  var $days = this.DNDTimer.$input('days');
  var $hours = this.DNDTimer.$input('hours');
  var $minutes = this.DNDTimer.$input('minutes');

  this.DNDTimer.submit(function()
  {
    var days_val = $.trim($days.val());
    if (!days_val.length) {
      $days.val('0');
      days_val = 0;
    } else {
      days_val = parseInt(days_val, 10);
    }

    if (isNaN(days_val) || days_val < 0) {
      alert('Укажите правильное количество дней');
      $days.focus().select();
      return false;
    }

    var hours_val = $.trim($hours.val());
    if (!hours_val.length) {
      $hours.val('0');
      hours_val = 0;
    } else {
      hours_val = parseInt(hours_val, 10);
    }

    if (isNaN(hours_val) || hours_val < 0 || hours_val > 23) {
      alert('Укажите правильное количество часов (от 0 до 23)');
      $hours.focus().select();
      return false;
    }

    var minutes_val = $.trim($minutes.val());
    if (!minutes_val.length) {
      $minutes.val(minutes_val).focus();
      return false;
    } else {
      minutes_val = parseInt(minutes_val, 10);
    }

    if (isNaN(minutes_val) || minutes_val < 0 || minutes_val > 59) {
      alert('Укажите правильное количество минут (от 0 до 59)');
      $minutes.focus().select();
      return false;
    }

    ServiceProfile.DNDTimer.stopTimer();
    
    ServiceProfile.sendRequest(
      40, 5, [days_val, hours_val, minutes_val],
      'DNDTimerSetup',
      function(status, $response) {
        if (status != 'success') { return; }

        var $dndEndDate = $response.children('#DNDEndDate');
        if ($dndEndDate.length) {
          ServiceProfile.DNDTimer.setupTimer($dndEndDate.text());
        }
      });
    
    return false;
  });

  var $dndEndDate = $('#service-40').find('.service_controls > .custom_controls > #DNDEndDate');

  if ($dndEndDate.length) {
    ServiceProfile.DNDTimer.setupTimer($dndEndDate.text());
    $dndEndDate.remove();
  }
}


function SelfCare_SendSMSForm()
{
  this.DOMConstruct('#sms_box');

  this.$input('ShortMSISDN').setOnEmptyValueLabel('Номер');

  if ($.browser.mozilla) {
    this.$input('PrefixSelector').$input.css('top', '-1px');
  }
}
SelfCare_SendSMSForm.prototype = new SelfCare_Form;


function SelfCare_SendSMS()
{
  var SendSMSForm = new SelfCare_SendSMSForm();

  SendSMSForm.submit(function()
  {
    var prefix_val = SendSMSForm.$input('PrefixSelector').val();

    var $short_msisdn = SendSMSForm.$input('ShortMSISDN');
    var short_msisdn_val = $.trim($short_msisdn.val());
    if (!/^\d{6}$/.test(short_msisdn_val)) {
      $short_msisdn.focus().select();
      return false;
    }

    var $textarea = SendSMSForm.$input('ShortMessageText');
    var text = $.trim($textarea.val());
    if (text.length == 0) {
      $textarea.focus();
      return false;
    }

    SelfCare.request(
      '_next', [prefix_val, short_msisdn_val, text],
      'SendSMS',
      function(status, $response) {
        if (status != 'success') { return false; }
        var $sendstatus = $response.children('#SendStatus');
        if ($sendstatus.text() == 'sent') {
          $textarea.val('');
        }
      }
    );

    return false;
  });

  var text_max_bytes = 135;

  SendSMSForm.$input('ShortMessageText')
    .bind('keyup', function()
    {
      var escapedStr = encodeURI(this.value);
      if (escapedStr.indexOf("%") != -1) {
        var count = escapedStr.split("%").length - 1;
        if (count == 0) count++;  //perverse case; can't happen with real UTF-8
        count += (escapedStr.length - (count * 3));
      } else {
        count = escapedStr.length;
      }

      var mod = text_max_bytes - count;

      if (mod >= 0) {
        $('#sms_text_statusbar .sms_text_warning').hide();
        $('#sms_text_statusbar .count').text(count);
        $('#sms_text_statusbar .mod').text(mod);
        $('#sms_text_statusbar .sms_text_info').show();
      }
      else {
        $('#sms_text_statusbar .sms_text_info').hide();
        $('#sms_text_statusbar .overcount').text(count - text_max_bytes);
        $('#sms_text_statusbar .sms_text_warning').show();
      }
    });
}




// Melody player
var prev_img_id = null;

function ImageOn(image_id) {
  $('#' + image_id)
    .attr('src', url_Images + 'melody-on.gif');
}

function PrevImageOff() {
  $('#' + prev_img_id)
    .attr('src', url_Images + 'melody-off.gif');
}

function TogglePlay(melody_id, image_id)
{
	if (prev_img_id != image_id)
	{
    if (prev_img_id) {
     	PrevImageOff();
      StopMelody();
    }

    ImageOn(image_id);
    PlayMelody(melody_id);

    prev_img_id = image_id;
	}
	else {
    PrevImageOff();
    StopMelody();
    prev_img_id = null;
	}

	return false;
}

function PlayMelody(melody_id)
{
	try {
    var javaObject = $("#Audio")[0];
    javaObject.audioClipURL = '../../../download.file?storage=000&param1=' + melody_id + '.wav';
    javaObject.Load();
    javaObject.Play();
	}
	catch(ex) { }
}

function StopMelody()
{
	try {
		$('#Audio').get(0).Stop();
	}
  catch(ex) { }
}


function SelfCare_DefaultMelodyForm()
{
  this.DOMConstruct('#default_melody_form');

  var $select = this.$form.find('#default_melody_id_select');
  
  $select.children('.empty:eq(0)')
    .val('-1').text('Мелодия по умолчанию');
}
SelfCare_DefaultMelodyForm.prototype = new SelfCare_Form;


function SelfCare_SearchForm(container, onempty_value)
{
  $(container)
    .append(
    '<form action="" onsubmit="return false;">' +
      '<input type="text" name="search_phrase"/>' +
      '<input type="submit" value="search" style="display: none;"/>' +
    '</form>'
    );

  this.DOMConstruct(container);

  this.$input('search_phrase')
    .setOnEmptyValueLabel(onempty_value);
}
SelfCare_SearchForm.prototype = new SelfCare_Form;

function SelfCare_RBTMelodySearchForm(selector)
{
  $(selector)
    .append(
    '<form action="" onsubmit="return false;">' +
      '<input type="text" name="search_phrase"/>' +
      '<input type="submit" value="search" style="display: none;"/>' +
    '</form>'
    );

  this.DOMConstruct(selector);

  this.$input('search_phrase')
    .setOnEmptyValueLabel('Поиск мелодий');

}
SelfCare_RBTMelodySearchForm.prototype = new SelfCare_Form;


// [RBT Melody Shop]
function SelfCare_RBTMelodyShop()
{
  $('#change_default_melody_btn')
    .click(function() {
      $('#rbt_user_melody_list .default_melody_info_row').hide();
      $('#default_melody_form_row').show();
    });

  var DefaultMelodyForm = new SelfCare_DefaultMelodyForm;
  var default_melody_id_value = $.trim($('#default_melody_id_value').text());

  DefaultMelodyForm
    .submit(function() {
      var melody_id = $('#default_melody_id_select').val();
      if (melody_id != default_melody_id_value) {
        SelfCare.request('_next', ['SetDefaultMelody', melody_id, ''], 'content');
      }
      else {
        $('#default_melody_form_row').hide();
        $('#rbt_user_melody_list .default_melody_info_row').show();
      }
      return false;
    });

  SelfCare_setSelectValue($('#default_melody_id_select').get(0), default_melody_id_value);
  
  $('#digit_list, #eng_letters, #rus_letters')
    .each(function() {
      var $this = $(this);
      var symb_list = $this.text().split(',');
      $this.empty();

      var i = 0, symb;
      for (; symb = symb_list[i]; i++)
      {
        $('<a href="#"/>')
          .text(symb)
          .click(SelfCare_RBTMelodyShop.prototype.AlphabetSymbolClick)
          .appendTo($this);

        if ((i + 1) != symb_list.length) {
          $this.append(' - ');
        }
      }
    });

  $('#rbt_gerne_list > li > a')
    .click(SelfCare_RBTMelodyShop.prototype.GenreClick);

  this.SearchForm = new SelfCare_RBTMelodySearchForm('#melody_search_form');
  this.SearchForm.submit(SelfCare_RBTMelodyShop.prototype.SearchFormSubmit);

  this.renderContentTable($('#content_melodies_data'));
}

SelfCare_RBTMelodyShop.prototype =
{
  
  /**
   * On content loaded callback.
   * 
   * @param status
   * @param $response
   */
  OnContentLoaded: function(status, $response)
  {
    if (status != 'success') { return; }
    
    var $data_table = $response.children('#content_melodies_data');
    if ($data_table.length) {
      SelfCare.current_page_handler.renderContentTable($data_table);
    }
  },

  /**
   * Play melody button click delegate.
   */
  playMelody: function(/*event*/)
  {
    //var data = event.data;
    //TogglePlay(data.melody_id, image_id);
    return false;
  },

  /**
   * Hide Info delegate.
   */
  hideInfo: function() {
    window.PageShader.hide();
  },

  /**
   * Purchase melody delegate.
   *
   * @param event
   */
  purchaseMelody: function(event)
  {
    var data = event.data;
    
    SelfCare.request(
        '_next', ['PurchaseMelody', data.melody_id, ''],
        'content',
        function(status) {
          if (status != 'success') { return; }
          window.PageShader.hide();
        });
  },

  /**
   * Show Purchase information delegate
   * 
   * @param event
   */
  showPurchaseInfo: function(event)
  {
    var data = event.data;

    var $content = $(
      '<div class="buy_melody_form">' +
        '<h3>Покупка мелодии</h3>' +
        '<p>Название: <b>' + data.melody_name + '</b></p>' +
        '<p>Исполнитель: <b>' + data.singer_name + '</b></p>' +
        '<p>Жанр: <b>' + data.genre_name + '</b></p>' +
        '<p>Стоимость: <b>' + data.price + '</b> сом</p>' +
        '<div class="buy_button_host"/>' +
        '<div class="cancel_button_host"/>' +
      '</div>');

    SelfCare_CreateButton('Купить', 'button')
        .appendTo($content.children('.buy_button_host'))
        .find('input[type=button]').bind('click', {melody_id: data.melody_id}, SelfCare_RBTMelodyShop.prototype.purchaseMelody);

    SelfCare_CreateButton('Отмена', 'button')
        .appendTo($content.children('.cancel_button_host'))
        .find('input[type=button]').click(SelfCare_RBTMelodyShop.prototype.hideInfo);

    window.PageShader.show($content.get(0));

    return false;
  },

  makePresentFormSubmit: function(event)
  {
    var data = event.data;

    var $anumber_input = $(this).find('input[type=text]'),
        anumber = $.trim($anumber_input.val());

    if (!anumber.length) {
      alert('Введите номер получателя');
      $anumber_input.focus();
    }
    else if (!/\d{9,12}/.test(anumber)) {
      alert('Номер введён неверно');
      $anumber_input.focus().select();
    }
    else {
      SelfCare.request(
          '_next', ['PurchaseMelodyFriend', data.melody_id, anumber],
          'PurchaseMelodyFriend',
          function(status) {
            if (status != 'success') { return; }
            window.PageShader.hide();
          });
    }

    return false;
  },

  /**
   * Show Make Present information handler.
   * 
   * @param event
   */
  showMakePresentInfo: function(event)
  {
    var data = event.data;

    var $content = $(
      '<div class="buy_melody_form">' +
        '<h3>Покупка мелодии в подарок</h3>' +
        '<p>Название: <b>' + data.melody_name + '</b></p>' +
        '<p>Исполнитель: <b>' + data.singer_name + '</b></p>' +
        '<p>Жанр: <b>' + data.genre_name + '</b></p>' +
        '<p>Стоимость: <b>' + data.price + '</b> сом</p>' +
        '<div class="present_form_host">' +
          '<form action="" onsubmit="return false;"/>' +
        '</div>' +
        '<div class="cancel_button_host"/>' +
      '</div>');

    var $present_form = $content.find('.present_form_host > form');


    SelfCare_CreateInput({
      type: 'text',
      name: 'anumber',
      maxlength: '12'
    })
        .css('float', 'left')
        .appendTo($present_form);
    
    SelfCare_CreateButton('Подарить', 'submit')
        .css('marginLeft', '5px')
        .appendTo($present_form);
    
    $present_form.bind('submit', {melody_id: data.melody_id}, SelfCare_RBTMelodyShop.prototype.makePresentFormSubmit);

    SelfCare_CreateButton('Отмена', 'button')
        .appendTo($content.children('.cancel_button_host'))
        .find('input[type=button]').click(SelfCare_RBTMelodyShop.prototype.hideInfo);

    window.PageShader.show($content.get(0));

    return false;
  },

  /**
   * Page click delegate.
   */
  PageClick: function()
  {
    SelfCare.request(
      '_next', ['Paging', $(this).text(), ''],
      'MelodyDataTable', SelfCare_RBTMelodyShop.prototype.OnContentLoaded
    );

    return false;
  },

  /**
   * Render Content using DOM data table.
   *
   * @param $data_table
   */
  renderContentTable: function($data_table)
  {
    var $content_melodies_tbody = $('#content_melodies > tbody');
    $content_melodies_tbody.empty();

    var cells_per_row = 3, cell_counter, $row;
    
    $data_table.find('tbody > tr')
      .each(function(i, data_row)
      {
        var $data_row = $(data_row);

        if (!cell_counter) {
          cell_counter = cells_per_row;
          $row = $('<tr/>').appendTo($content_melodies_tbody);
        }
        else {
          $row = $content_melodies_tbody.children('tr:last');
        }

        $row.append('<td class="melody_cell-left"/>');

        var $cell = $('<td class="melody_cell"/>').appendTo($row);

        var $div = $(
          '<div>' +
            '<b class="melody_name"/>' +
            '<br/>' +
            '<span class="singer_name"/>' +
          '</div>'
          ).appendTo($cell);

        var data = {
          melody_id: $data_row.children('.MELODY_ID').text(),
          melody_name: $data_row.children('.MELODY_TITLE').text(),
          singer_name: $data_row.children('.SINGER_NAME').text(),
          genre_name: $data_row.children('.GENRE_NAME').text(),
          price: $data_row.children('.PRICE').text()
        };

        $div.children('.melody_name').text(data.melody_name);
        $div.children('.singer_name').text(data.singer_name);

        var $controls = $(
          '<td class="melody_cell-controls">' +
            '<a href="#" title="Прослушать" class="play_melody_button" onclick="TogglePlay(\'' + data.melody_id + '\', \'img_shop_' + data.melody_id + '\')">' +
              '<img src="' + url_Images + 'melody-off.gif" id="img_shop_' + data.melody_id + '" hspace="0" vspace="0" align="absmiddle"/>' +
            '</a>' +
            '<a href="#" class="buy_melody_button" title="Купить"/>' +
            '<a href="#" class="present_melody_button" title="Подарить другу"/>' +
          '</td>'
          ).appendTo($row);

        $controls.children('.play_melody_button')
          .bind('click', data, SelfCare_RBTMelodyShop.prototype.playMelody);

        $controls.children('.buy_melody_button')
          .bind('click', data, SelfCare_RBTMelodyShop.prototype.showPurchaseInfo);

        $controls.children('.present_melody_button')
          .bind('click', data, SelfCare_RBTMelodyShop.prototype.showMakePresentInfo);


        if (--cell_counter) {
          $row.append('<td class="delimiter"/>');
        } else {
          $content_melodies_tbody
            .append('<tr class="delimiter"><td/></tr>');
        }
      });

    if (cell_counter) {
      $row.append('<td/>')
        .after('<tr class="delimiter"><td/></tr>');
    }

    // generating pages
    var $bottom_data_cell = $data_table.find('tfoot > tr > td');
    var pages_count = parseInt($bottom_data_cell.children('.pages_count').text(), 10);
    var active_page = parseInt($bottom_data_cell.children('.active_page').text(), 10);

    var $paging_cell = $('#content_melodies_paging');
    $paging_cell.empty();

    var i = 1, $a;
    for (; i <= pages_count; i++)
    {
      $a = $('<a href="#" class="page_button"/>')
        .text(i)
        .click(this.PageClick)
        .appendTo($paging_cell);

      if (i == active_page) {
        $a.addClass('active');
      }
    }
  },


  AlphabetSymbolClick: function()
  {
    $('#rbt_gerne_list > .active').removeClass('active');

    var $this = $(this);
    
    $this.siblings('.active').removeClass('active');
    $this.addClass('active');
    
    SelfCare.request(
      '_next', ['FindLetter', $this.text(), ''],
      'MelodyDataTable', SelfCare_RBTMelodyShop.prototype.OnContentLoaded
    );
    
    return false;
  },


  genre_id_parser: /^rbt_genre_(\d+)$/,
  
  GenreClick: function()
  {
    $('#alphabet_menu > span > .active').removeClass('active');
    
    var $parent = $(this.parentNode);

    $parent.siblings('.active').removeClass('active');
    $parent.addClass('active');

    var genre_id = SelfCare_RBTMelodyShop.prototype.genre_id_parser.exec($parent.attr('id'))[1];
    SelfCare.request(
      '_next', ['FindGenre', genre_id, ''],
      'MelodyDataTable', SelfCare_RBTMelodyShop.prototype.OnContentLoaded
    );

    return false;
  },

  SearchFormSubmit: function()
  {
    $('#alphabet_menu > span > .active, #rbt_gerne_list > .active').removeClass('active');
    
    var $phrase = SelfCare.current_page_handler.SearchForm.$input('search_phrase');
    var phrase = $.trim($phrase.val());

    if (!phrase.length) {
      $phrase.val('').focus();
    }
    else {
      SelfCare.request('_next', ['FindPhrase',  phrase, ''], 'MelodyDataTable', SelfCare_RBTMelodyShop.prototype.OnContentLoaded);
    }

    return false;
  }
};




// [RBT Groups & Contacts]

function SelfCare_RuleTypeFormPrototype()
{
  this.addItem = function($data_row)
  {
    var $last_tr = this.$form.find('.rule_item_row:last');
    var $clone = $last_tr.clone(true).css('display', 'none');

    $last_tr.parent()
      .append('<tr><td colspan="7" style="font-size: 5px">&nbsp;</td></tr>')
      .append($clone);

    if (typeof $data_row != 'undefined')
    {
      this.setItemValue($clone, $data_row);
      $clone.find('.rule_item_checkbox')
        .val($data_row.find('.entry_id').text());
    }
    else {
      this.resetItemValue($clone);
      $clone.find('.rule_item_checkbox').val('0');
    }

    $clone.css('display', 'table-row');
  };

  this.setState = function($data_table)
  {
    var self = this;

    this.reset();

    $data_table.find('tbody > tr')
      .each(function(i, data_row) {
        var $data_row = $(data_row);
        if (i == 0) {
          var $tr_first = self.$form.find('.rule_item_row:first');
          self.setItemValue($tr_first, $data_row);
          $tr_first.find('.rule_item_checkbox')
            .val($data_row.find('.entry_id').text());
        } else {
          self.addItem($data_row);
        }
      });
  };

  this.reset = function() {
    var $tr_first = this.$form.find('.rule_item_row:first');
    $tr_first.nextAll().remove();
    this.resetItemValue($tr_first);
    $tr_first.find('.rule_item_checkbox').val('0');
  };

  this.onsubmit = function(form)
  {
    var self = this;

    var operation = new SelfCare_RBTOperation('EditRule');
    var error = null; // exception

    if (this.old_type_id && this.old_type_id != 0) {
      $('#rule_' + this.rule_id + '_data tr')
        .each(function(i, data_row) {
          var entry_id = $.trim($(data_row).children('.entry_id').text());
          operation.addAction('RemoveRuleItem', [entry_id]);
        });
    }

    $(form).find('.rule_item_checkbox')
      .each(function()
      {
        var $this = $(this);
        var $tr = $this.closest('tr');

        var entry_id = $this.val();

        if (!$this.attr('checked')) {
          if (entry_id != 0) {
            operation.addAction('RemoveRuleItem', [entry_id]);
          }
          return;
        }
        else {
          try {
            var values = self.getItemValue($tr);
          }
          catch (e) {
            error = e;
            return false;
          }
        }

        if (entry_id != 0)
        {
          // TODO: compare affections
          operation.addAction('UpdateRuleItem', [entry_id, values[0], values[1], values[2]]);
        }
        else {
          var rule_id = !self.old_type_id ? self.rule_id : 0;
          operation.addAction('AddRuleItem', [values[0], values[1], values[2], rule_id]);
        }
      });

    if (error) {
      if (typeof error.message != 'undefined') {
        alert(error.message);
      }
      if (typeof error.$input != 'undefined') {
        error.$input.focus();
      }
      if (typeof error.$tr != 'undefined') {
        highlightErrorRow(error.$tr);
      }
      return false;
    }

    if (typeof this.checkInputs != 'undefined'
        && !this.checkInputs()) {
      return false;
    }

    if (!operation.length) {
      // trying to get first melody select
      var $melody_id = this.$input('melody_id');
      if ($melody_id) {
        $melody_id.focus();
      }
      return false;
    }

    if (this.old_type_id) {
      try {
        SelfCare.current_page_handler.addLinkToSelectedItem(operation, this.rule_type_id, 0);
      }
      catch (e) {
        alert(e.message);
        return false;
      }
    }

    operation.commit();
  };

}
SelfCare_RuleTypeFormPrototype.prototype = new SelfCare_Form;


function blinkOnceErrorRow($tr) {
  $tr.css('background', '#CF0000');
  setTimeout(function() { $tr.css('background', ''); }, 250);
}

function highlightErrorRow($tr) {
  setTimeout(function() { blinkOnceErrorRow($tr); }, 0);
  setTimeout(function() { blinkOnceErrorRow($tr); }, 500);
  setTimeout(function() { blinkOnceErrorRow($tr); }, 1000);
}

var SelfCare_RuleTypeForms =
{
  // Single Melody
  0: {
    setState: function($data_table) {
      this.$curr_data_table = $data_table;
      var select = this.$input('melody_id').$input.get(0);
      var melody_id = $data_table.find('.link').text();
      SelfCare_setSelectValue(select, melody_id);
    },

    reset: function() {
      this.$curr_data_table = null;
      SelfCare_setSelectValue(this.$input('melody_id').$input.get(0), 0);
    },

    onsubmit: function()
    {
      var $melody_id = this.$input('melody_id');
      var melody_id = $melody_id.val();

      var curr_melody_id = this.$curr_data_table ? this.$curr_data_table.find('.link').text() : '-1';
      if (melody_id == curr_melody_id) {
        return false; // melody not changed
      }

      var operation = new SelfCare_RBTOperation('EditRule');

      if (this.old_type_id) {
        $('#rule_' + this.rule_id + '_data tr')
          .each(function(i, data_row) {
            var entry_id = $.trim($(data_row).children('.entry_id').text());
            operation.addAction('RemoveRuleItem', [entry_id]);
          });
      }

      SelfCare.current_page_handler.addLinkToSelectedItem(operation, 0, melody_id);
      operation.commit();
    }
  },

  // Rule typeof Calendar
  2: {
    setItemValue: function($tr, $data_row) {
      $tr.find('input[name=StartDate]').val($data_row.find('.start_bound').text());
      $tr.find('input[name=EndDate]').val($data_row.find('.stop_bound').text());
      SelfCare_setSelectValue($tr.find('select[name=melody_id]').get(0), $data_row.find('.link').text());
    },

    getItemValue: function($tr)
    {
      var $start_date = $tr.find('input[name=StartDate]');
      var start_date = $.trim($start_date.val());
      if (!SelfCare_date_format_regex.test(start_date)) {
        throw {message: 'Неверный формат даты', $input: $start_date, $tr: $tr};
      }

      var $end_date = $tr.find('input[name=EndDate]');
      var end_date = $.trim($end_date.val());
      if (!SelfCare_date_format_regex.test(end_date)) {
        throw {message: 'Неверный формат даты', $input: $end_date, $tr: $tr};
      }

      var start_stamp = getDateFromFormat(start_date, SelfCare_calendar_date_format);
      var end_stamp = getDateFromFormat(end_date, SelfCare_calendar_date_format) + 86399; // + 23:59:59

      if (start_stamp > end_stamp) {
        throw {message: 'Неверно задан временной интервал', $input: $end_date, $tr: $tr};
      }

      var $melody_id = $tr.find('select[name=melody_id]');
      var melody_id = $melody_id.val();
      if (!melody_id) {
        throw {message: 'Выберите мелодию', $input: $melody_id, $tr: $tr};
      }

      return [start_date, end_date, melody_id];
    },

    resetItemValue: function($tr) {
      var default_value = formatDate(new Date(), SelfCare_calendar_date_format);
      $tr.find('input[name=StartDate]').val(default_value);
      $tr.find('input[name=EndDate]').val(default_value);
      SelfCare_setSelectValue($tr.find('select[name=melody_id]').get(0), 0);
    },

    checkInputs: function()
    {
      var rows_data = [], error = false;

      $('#rule_type_2_form .rule_item_row')
        .each(function(i, tr)
        {
          var $tr = $(tr),
              $date_inputs = $tr.find('input.input_date'),
              $start = $date_inputs.filter('[name=StartDate]'),
              $end = $date_inputs.filter('[name=EndDate]'),
              start_val = $start.val(),
              end_val = $end.val();

          var start_a = SelfCare_date_format_regex.exec(start_val),
              end_a = SelfCare_date_format_regex.exec(end_val);

          if (!start_a || !end_a)
          {
            error = true;
            alert('Неверный формат даты');
            if (!start_a) {
              $start.focus().select();
            } else {
              $end.focus().select();
            }
            highlightErrorRow($tr);
            return false;
          }
          
          var start_time = (new Date(start_a[4], start_a[3], start_a[2], 0, 0, 0)).getTime() / 1000,
              end_time = (new Date(end_a[4], end_a[3], end_a[2], 23, 59, 59)).getTime() / 1000;

          var $error_tr = null;

          $(rows_data)
            .each(function(i, item)
            {
              if (start_time >= item.start_time && start_time <= item.end_time) {
                error = true;
                $error_tr = item.$tr;
                return false;
              }
              
              if (end_time >= item.start_time && end_time <= item.end_time) {
                error = true;
                $error_tr = item.$tr;
                return false;
              }

              if (item.start_time >= start_time && item.start_time <= end_time) {
                error = true;
                $error_tr = item.$tr;
                return false;
              }

              if (item.end_time >= start_time && item.end_time <= end_time) {
                error = true;
                $error_tr = item.$tr;
                return false;
              }
            });

          if (error) {
            alert('Интервалы дат пересекаются');
            highlightErrorRow($error_tr);
            highlightErrorRow($tr);
            return false;
          }

          rows_data.push({
            start_time: start_time,
            end_time: end_time,
            $tr: $tr
          });
          
        });
      
      return !error;
    }
  },

  // Rule typeof WeekDays
  3: {
    setItemValue: function($tr, $data_row) {
      SelfCare_setSelectValue($tr.find('select[name=WeekDay]').get(0), $data_row.find('.start_bound').text());
      SelfCare_setSelectValue($tr.find('select[name=melody_id]').get(0), $data_row.find('.link').text());
    },

    getItemValue: function($tr)
    {
      var week_day = $tr.find('select[name=WeekDay]').val();

      var $melody_id = $tr.find('select[name=melody_id]');
      var melody_id = $melody_id.val();
      if (!melody_id) {
        throw {message: 'Выберите мелодию', $input: $melody_id};
      }

      return [week_day, week_day, melody_id];
    },

    resetItemValue: function($tr) {
      SelfCare_setSelectValue($tr.find('select[name=WeekDay]').get(0), 1);
      SelfCare_setSelectValue($tr.find('select[name=melody_id]').get(0), 0);
    },

    checkInputs: function()
    {
      var rows_data = [], error = false;

      $('#rule_type_3_form .rule_item_row')
        .each(function(i, tr)
        {
          var $tr = $(tr),
              week_day = $tr.find('select[name=WeekDay]').val();

          var $error_tr = null;

          $(rows_data)
            .each(function(i, item)
            {
              if (week_day == item.week_day) {
                error = true;
                $error_tr = item.$tr;
                return false;
              }
            });

          if (error) {
            alert('Дни недели пересекаются');
            highlightErrorRow($error_tr);
            highlightErrorRow($tr);
            return false;
          }

          rows_data.push({
            week_day: week_day,
            $tr: $tr
          });

        });

      return !error;
    }
  },

  // Rule typeof 24Hours
  4: {
    setTimeInputValue: function($input, value) {
      var value_list = value.split(':');
      if (typeof value_list[2] == 'undefined') {
        value_list[2] = '00';
      }

      $input.nextAll('.input_time_item')
        .each(function(i) {
          this.value = value_list[i];
        });
    },

    setItemValue: function($tr, $data_row) {
      this.setTimeInputValue($tr.find('input[name=StartTime]'), $data_row.find('.start_bound').text());
      this.setTimeInputValue($tr.find('input[name=EndTime]'), $data_row.find('.stop_bound').text());
      SelfCare_setSelectValue($tr.find('select[name=melody_id]').get(0), $data_row.find('.link').text());
    },


    getTimeInputValueList: function($input)
    {
      var value_list = [];

      $input.nextAll('.input_time_item')
        .each(function(i) {
          value_list[i] = this.value;
        });

      return value_list;
    },

    getItemValue: function($tr)
    {
      var start_time_list = this.getTimeInputValueList($tr.find('input[name=StartTime]'));
      var end_time_list = this.getTimeInputValueList($tr.find('input[name=EndTime]'));

      var start_time_stamp = (new Date(1970, 0, 1, start_time_list[0], start_time_list[1], start_time_list[2])).getTime();
      var end_time_stamp = (new Date(1970, 0, 1, end_time_list[0], end_time_list[1], end_time_list[2])).getTime();

      if (start_time_stamp >= end_time_stamp) {
        throw {
          message: 'Неверно задан временной интервал',
          $input: $tr.find('input[name=EndTime]').siblings('.input_hours'),
          $tr: $tr
        };
      }

      var $melody_id = $tr.find('select[name=melody_id]');
      var melody_id = $melody_id.val();
      if (!melody_id) {
        throw {message: 'Выберите мелодию', $input: $melody_id, $tr: $tr};
      }

      return [start_time_list.join(':'), end_time_list.join(':'), melody_id];
    },

    resetItemValue: function($tr) {
      this.setTimeInputValue($tr.find('input[name=StartTime]'), '0:00:00');
      this.setTimeInputValue($tr.find('input[name=EndTime]'), '0:00:00');
      SelfCare_setSelectValue($tr.find('select[name=melody_id]').get(0), 0);
    },
    
    checkInputs: function()
    {
      var rows_data = [], error = false;

      var rule_type_form = this;
      
      $('#rule_type_4_form .rule_item_row')
        .each(function(i, tr)
        {
          var $tr = $(tr),
              row_values = rule_type_form.getItemValue($tr),
              start_val = row_values[0],
              end_val = row_values[1],
              start_a = start_val.split(':'),
              end_a = end_val.split(':');

          var start_time = (new Date(1970, 0, 1, start_a[0], start_a[1], start_a[2])).getTime() / 1000,
              end_time = (new Date(1970, 0, 1, end_a[0], end_a[1], end_a[2])).getTime() / 1000;

          var $error_tr = null;

          $(rows_data)
            .each(function(i, item)
            {
              if (start_time >= item.start_time && start_time <= item.end_time) {
                error = true;
                $error_tr = item.$tr;
                return false;
              }

              if (end_time >= item.start_time && end_time <= item.end_time) {
                error = true;
                $error_tr = item.$tr;
                return false;
              }

              if (item.start_time >= start_time && item.start_time <= end_time) {
                error = true;
                $error_tr = item.$tr;
                return false;
              }

              if (item.end_time >= start_time && item.end_time <= end_time) {
                error = true;
                $error_tr = item.$tr;
                return false;
              }
            });

          if (error) {
            alert('Интервалы дат пересекаются');
            highlightErrorRow($error_tr);
            highlightErrorRow($tr);
            return false;
          }

          rows_data.push({
            start_time: start_time,
            end_time: end_time,
            $tr: $tr
          });

        });

      return !error;
    }
  },

  // Rule typeof Playlist
  5: {
    setItemValue: function($tr, $data_row) {
      SelfCare_setSelectValue($tr.find('select[name=melody_id]').get(0), $data_row.find('.link').text());
    },

    getItemValue: function($tr) {
      var $melody_id = $tr.find('select[name=melody_id]');
      var melody_id = $melody_id.val();
      if (!melody_id) {
        throw {message: 'Выберите мелодию', $input: $melody_id};
      }
      return [-1, -1, melody_id];
    },

    resetItemValue: function($tr) {
      SelfCare_setSelectValue($tr.find('select[name=melody_id]').get(0), 0);
    }
  }

};


// rule type form constructor
function SelfCare_RuleTypeForm(type_id)
{
  this.rule_type_id = type_id;

  for (var prop in SelfCare_RuleTypeForms[type_id]) {
    this[prop] = SelfCare_RuleTypeForms[type_id][prop];
  }
}
SelfCare_RuleTypeForm.prototype = new SelfCare_RuleTypeFormPrototype;


var SelfCare_rule_type_form_instances;

function SelfCare_getRuleTypeFormInstance(type_id)
{
  if (typeof SelfCare_rule_type_form_instances[type_id] != 'undefined') {
    return SelfCare_rule_type_form_instances[type_id];
  }

  var form = new SelfCare_RuleTypeForm(type_id);
  form.DOMConstruct('#rule_type_' + type_id + '_form');

  if (type_id != 0) {
    form.$form.find('.add_item')
      .click(function() {
        form.addItem();
        return false;
      });
  }
  else {
    form.$form.find('select[name=melody_id] > .empty')
      .val('-1').text('Мелодия по умолчанию');
  }

  form.submit(function() {
    form.onsubmit(this);
  });

  SelfCare_rule_type_form_instances[type_id] = form;

  return form;
}


var SelfCare_change_rule_type_in_progress;

function SelfCare_showRuleForm(type_id, rule_id)
{
  SelfCare_change_rule_type_in_progress = false;

  var form = SelfCare_getRuleTypeFormInstance(type_id);

  form.rule_id = rule_id;
  form.old_type_id = null;

  if (rule_id != '-1') {
    form.setState($('#rule_' + rule_id + '_data'));
  }
  else {
    form.reset();
  }
  
  form.$container.siblings().hide();
  form.$container.show();

  $('#rule_type_forms:hidden')
    .css('width', '0px')
    .show()
    .animate({width: '460px'}, 'fast');
}


function SelfCare_changeCurrentRuleType(rule_id, old_type_id, new_type_id)
{
  if (old_type_id == new_type_id) {
    SelfCare_showRuleForm(old_type_id, rule_id);
    SelfCare_change_rule_type_in_progress = true;
    return true;
  }

  var form = SelfCare_getRuleTypeFormInstance(new_type_id);

  if (!SelfCare_change_rule_type_in_progress && (old_type_id != 0 || rule_id != -1) && !confirm(
    'При смене типа правила настройки текущего будут потеряны. Продолжить?'
  )) {
    return false;
  }

  SelfCare_change_rule_type_in_progress = true;

  form.rule_id = rule_id;
  form.old_type_id = old_type_id;

  form.reset();

  form.$container.siblings().hide();
  form.$container.show();

  return true;
}



function SelfCare_EditGroupForm()
{
  this.DOMConstruct('#edit_group_form');

  this.$input('group_name').setOnEmptyValueLabel('Название');
}
SelfCare_EditGroupForm.prototype = new SelfCare_Form;


function SelfCare_EditContactForm()
{
  this.DOMConstruct('#edit_contact_form');

  this.$input('contact_name').setOnEmptyValueLabel('Имя');
  this.$input('phone_num').setOnEmptyValueLabel('Номер');
}
SelfCare_EditContactForm.prototype = new SelfCare_Form;


function SelfCare_RBTOperation(operation_id)
{
  var trows_xml = '';

  this.length = 0;

  this.addAction = function(action_id, params)
  {
    trows_xml += '<row><columns><column>' + action_id + '</column><column><table><rows><row><columns>';

    var i = 0;
    for (; i < params.length; i++) {
      trows_xml += '<column>' + params[i] + '</column>';
    }

    trows_xml += '</columns></row></rows></table></column></columns></row>';

    this.length++;
  };

  this.getXML = function() {
    return '<table><rows>' + trows_xml + '</rows></table>';
  };

  this.commit = function(oncomplete) {
    var context = SelfCare.current_page_handler.getContextParam();
    SelfCare.request('_next', [operation_id, this.getXML()], context, oncomplete);
  };
}


function SelfCare_RBTContacts()
{
  var RBTContacts = this;

  SelfCare_rule_type_form_instances = {};
  
  var $menu_lvl1_hover = $('#view_contacts'),
      $menu_lvl1_active = $menu_lvl1_hover;

  var $menu_lvl2_hover = null, $menu_lvl2_active = null;

  var timeout = null;

  var startTimeout = function()
  {
    if (timeout) {
      clearTimeout(timeout);
    }

    timeout = setTimeout(function() {
      $menu_lvl1_active.triggerHandler('mouseover');
      if ($menu_lvl2_active) {
        $menu_lvl2_active.triggerHandler('mouseover');
      }
    }, 2000);
  };

  var resetTimeout = function() {
    if (timeout) {
      clearTimeout(timeout);
      timeout = null;
    }
  };

  $('#contact_list_controls')
  .hover(
    function() { resetTimeout(); },
    function() { startTimeout(); }
  );

  $('#contact_list_controls > a')
    .mouseover(function() {
      if ($(this).hasClass('btn-disabled') || this.id == $menu_lvl1_hover.attr('id')) { return; }

      $menu_lvl1_hover.removeClass('btn-active');
      $('#' + $menu_lvl1_hover.attr('id') + '_status').hide();

      $menu_lvl1_hover = $(this).addClass('btn-active');
      $('#' + this.id + '_status').show();
    })
    .bind('activate', function() {
      var $prev_active_item = $menu_lvl1_active;

      $menu_lvl1_active = $(this);
      $menu_lvl1_active.triggerHandler('mouseover');

      $('#' + $prev_active_item.attr('id') + '_status')
        .find('.btn-active').removeClass('btn-active');
    })
    .click(function() { return false; });


  $('#create_functions_status > a, #edit_contact_status > a')
    .mouseover(function() {
      if ($(this).hasClass('btn-disabled') || ($menu_lvl2_hover && this.id == $menu_lvl2_hover.attr('id'))) { return; }

      if ($menu_lvl2_hover) {
        $menu_lvl2_hover.removeClass('btn-active');
      }
    
      $menu_lvl2_hover = $(this).addClass('btn-active');
    })
    .bind('activate', function() {
      $menu_lvl2_active = $(this);
      $menu_lvl2_active.triggerHandler('mouseover');
    });


  /* View contacts status handling */
  var $view_contacts_status = $('#view_contacts_status');

  this.setViewContactStatus = function(item_number) {
    $('#view_contacts').triggerHandler('activate');
    $view_contacts_status.children('.btn-active').removeClass('btn-active');
    $view_contacts_status.children('a:eq(' + (item_number - 1) + ')').addClass('btn-active');
  };


  var entry_parse = /^(group|anumber)_entry-(\d+)$/;
  var link_parse = /(?:^|\s)link_(\-?\d+)_(\d+)?(?:\s|$)/;

  var parseGroupEntry = function(dom_node)
  {
    var parsed = {
      id: entry_parse.exec(dom_node.id),
      className: link_parse.exec(dom_node.className)
    };

    return {
      entry_id: parsed.id[2],
      link_id: parsed.className[1],
      link_type: (typeof parsed.className[2] != 'undefined') ? parsed.className[2] : -1
    };
  };

  var parseANumberEntry = function(dom_node)
  {
    var parsed = {
      id: entry_parse.exec(dom_node.id),
      className: link_parse.exec(dom_node.className)
    };

    var anumber = { entry_id: parsed.id[2] };

    if (parsed.className) {
      anumber.link_id = parsed.className[1];
      anumber.link_type = parsed.className[2];
    }

    return anumber;
  };


  var selected = {
    group_id: null,
    anumber_id: null,
    link_id: null,
    link_type: null
  };

  this.getContextParam = function()
  {
    var context = 'content?selected=';
    
    context += selected.group_id ? selected.group_id : 'none';

    if (selected.anumber_id) {
      context += '/' + selected.anumber_id;
    }

    return context;
  };

  this.setContextState = function(context)
  {
    var selected = context.split('?selected=')[1].split('/');

    if (selected[0] != 'none') {
      $('#group_entry-' + selected[0]).triggerHandler('Select');
    }

    if (typeof selected[1] != 'undefined') {
      $('#anumber_entry-' + selected[1]).triggerHandler('Select');
    }
  };

  var ContactList = new GroupedListControl('#contact_list_groups');

  // adding additional ungrouped items
  $('#ungrouped_anumbers .item')
    .each(function() {
      ContactList.addItem(this);
    });


  var GroupSelectDelegate = function()
  {
    RBTContacts.cancelActiveAction();
    RBTContacts.setViewContactStatus(1);

    var group = parseGroupEntry(this);

    selected.anumber_id = null;
    selected.group_id = group.entry_id;
    selected.link_id = group.link_id;
    RBTContacts.activateRuleTypeIcon(group.link_type);

    RBTContacts.unlockRuleTypeButtons();

    $('#edit_contact.btn-disabled').removeClass('btn-disabled');
    $('#create_anumber_in_group.btn-disabled').removeClass('btn-disabled');

    SelfCare_showRuleForm(selected.link_type, selected.link_id);
  };

  if (ContactList.$groups) {
    ContactList.$groups.bind('Select', GroupSelectDelegate);
  }

  var ContactSelectDelegate = function()
  {
    RBTContacts.cancelActiveAction();

    var $group = $(this).closest('.group');

    if ($group.length) {
      RBTContacts.setViewContactStatus(1);
      selected.group_id = parseGroupEntry($group.get(0)).entry_id;
      $('#create_anumber_in_group').removeClass('btn-disabled');
    }
    else {
      RBTContacts.setViewContactStatus(2);
      selected.group_id = null;
      $('#create_anumber_in_group').addClass('btn-disabled');
    }

    var anumber = parseANumberEntry(this);

    selected.anumber_id = anumber.entry_id;
    selected.link_id = anumber.link_id;
    RBTContacts.activateRuleTypeIcon(anumber.link_type);

    RBTContacts.unlockRuleTypeButtons();

    $('#edit_contact').removeClass('btn-disabled');

    SelfCare_showRuleForm(selected.link_type, selected.link_id);
  };

  if (ContactList.$items) {
    ContactList.$items.bind('Select', ContactSelectDelegate);
  }

  ContactList.$list
    .bind('reset', function() {
      RBTContacts.lockRuleTypeButtons();

      $('#edit_contact').addClass('btn-disabled');
      $('#create_anumber_in_group').addClass('btn-disabled');

      selected.group_id = null;
      selected.anumber_id = null;
      selected.link_id = null;
      RBTContacts.activateRuleTypeIcon(-1);

      $('#rule_type_forms:visible')
        .animate({width: '0px'}, 'fast', function() { $(this).hide(); });
    });


  this.activateRuleTypeIcon = function(link_type)
  {
    $('#rule_types_menu .rule_type_button.active').removeClass('active');

    if (link_type != -1) {
      selected.link_type = link_type;
      $('#rule_type_' + link_type + '_button').addClass('active');
    }
    else {
      selected.link_type = null;
    }

    RBTContacts.showRuleTypeInfo(link_type);
  };

  this.lockRuleTypeButtons = function() {
    $('#rule_types_menu .rule_type_button').addClass('readonly');
  };

  this.unlockRuleTypeButtons = function() {
    $('#rule_types_menu .rule_type_button').removeClass('readonly');
  };

  this.showRuleTypeInfo = function(type_id)
  {
    var $curr_opened = $('#rule_types_info > div:visible');

    if ($curr_opened.length) {
      $curr_opened.fadeOut('fast', function() {
        if (type_id != -1) {
          RBTContacts.showRuleTypeInfo(type_id);
        }
      });
      return false;
    }

    $('#rule_type_'+type_id+'_info').fadeIn('fast');

    return false;
  };




  var EditGroupForm = new SelfCare_EditGroupForm();
  var EditContactForm = new SelfCare_EditContactForm();

  this.cancelActiveAction = function() {
    EditGroupForm.reset();
    EditContactForm.reset();
  };


  var phone_num_regex = /^\(?\+?(\d+)\)?$/;

  var parsePhoneNum = function($node) {
    var text = $.trim($node.text());
    var match = phone_num_regex.exec(text);
    return match ? match[1] : null;
  };

  var clicked = function(btn)
  {
    var $btn = $(btn);

    $btn.siblings('.btn-active').removeClass('btn-active');

    var parent_id = $btn.parent().attr('id');
    var anchor_id = parent_id.replace(/_status$/, '');
    $('#' + anchor_id).triggerHandler('activate');

    $btn.triggerHandler('activate');
    $btn.focus();
  };


  /**
   * Single operation reqest.
   *
   * @param operation_id String
   * @param params Array
   */
  var sendRequest = function(operation_id, params, oncomplete)
  {
    var operation = new SelfCare_RBTOperation(operation_id);
    operation.addAction(operation_id, params);
    operation.commit(oncomplete);
  };


  /* Function Buttons */

  var create_group_delegate = function()
  {
    clicked(this);

    RBTContacts.cancelActiveAction();
    ContactList.$list.triggerHandler('reset');

    $('#contact_list_groups')
      .append(EditGroupForm.$container);

    EditGroupForm
      .submit(function()
      {
        var $group_name = EditGroupForm.$input('group_name');
        var group_name_val = $.trim($group_name.val());
        if (!group_name_val.length) {
          $group_name.val('').focus();
          return false;
        }

        var $new_node = $(
          '<li class="group">' +
            '<div class="group_cap">' +
              '<a class="group_title" href="#"/>' +
            '</div>' +
          '</li>');

        $new_node.find('a').text(group_name_val);

        $('#contact_list_groups').append($new_node);

        sendRequest(
          'AddGroup', [group_name_val],
          function(status) {
            if (status != 'success') { return; }
            $("#contact_list_groups .group_title:contains('" + group_name_val + "')")
                .closest('.group').triggerHandler('Select');
          });

        EditGroupForm.reset();

        return false;
      });

    EditGroupForm.$form.find('.input_button input[type=submit]').val('Добавить');

    EditGroupForm.show();

    $(this).blur();
    EditGroupForm.$input('group_name').focus();

    return false;
  };

  $('#create_group').click(create_group_delegate);


  var create_anumber_delegate = function(event)
  {
    var $this = $(this);

    if ($this.hasClass('btn-disabled')) {
      $this.blur();
      return false;
    }

    clicked(this);

    RBTContacts.cancelActiveAction();

    var group_id, $group;

    if (event.data.create_in_group)
    {
      if (selected.group_id) {
        group_id = selected.group_id;
        $group = $('#group_entry-' + group_id);
      }
      else {
        alert('Не выбрана группа');
        return false;
      }

      ContactList.$list.triggerHandler('reset');

      $group.triggerHandler('expand');

      $group.find('.group_items')
        .append(EditContactForm.$container);
    }
    else
    {
      ContactList.$list.triggerHandler('reset');

      var $ul = $('#ungrouped_anumbers ul');

      if (!$ul.children().length)
      {
        $('#contact_list_divider_row, #contact_list_ungrouped_anumbers_row').show();

        EditContactForm
          .reset(function() {
            $('#contact_list_divider_row, #contact_list_ungrouped_anumbers_row').hide();
          });
      }

      $ul.append(EditContactForm.$container);
    }

    EditContactForm
      .submit(function()
      {
        var $contact_name = EditContactForm.$input('contact_name');
        var $phone_num = EditContactForm.$input('phone_num');
        var contact_name_val = $.trim($contact_name.val());
        var phone_num = $.trim($phone_num.val());

        if (!phone_num.length) {
          $phone_num.focus().select();
          return false;
        }
        else if (!/^(?:\+|0{1,2})[1-9]\d+$/.test(phone_num))
        {
          alert('Неверный формат телефонного номера');
          $phone_num.val(phone_num);
          $phone_num.focus().select();
          return false;
        }
        
        if (phone_num[0] == '0')
        {
          if (phone_num[1] == '0') {
            phone_num = '+' + phone_num.substr(2);
          }
          else {
            phone_num = '+996' + phone_num.substr(1);
          }
        }

        EditContactForm.reset();

        RBTContacts.createContact(phone_num, contact_name_val, group_id);

        return false;
      });

    EditContactForm.$form.find('.input_button input[type=submit]').val('Добавить');

    EditContactForm.show();

    $this.blur();
    EditContactForm.$input('contact_name').focus();

    return false;
  };

  $('#create_anumber')
    .bind('click', {create_in_group: false}, create_anumber_delegate);

  $('#create_anumber_in_group')
    .bind('click', {create_in_group: true}, create_anumber_delegate);


  $('#rename_contact')
    .click(function()
    {
      clicked(this);

      var $target;
      
      if (selected.anumber_id)
      {
        $target = $(ContactList.getSelectedItem());

        RBTContacts.cancelActiveAction();

        var $contact_name_input = EditContactForm.$input('contact_name');
        var $contact_name_node = $target.find('.contact_name');

        var curr_contact_name;
        if ($contact_name_node.length) {
          curr_contact_name = $.trim($contact_name_node.text());
        } else {
          curr_contact_name = '';
        }

        var $phone_num_input = EditContactForm.$input('phone_num');
        var $phone_num_node = $target.find('.phone_num');
        var phone_num = parsePhoneNum($phone_num_node);

        $phone_num_input.hide();

        $('<span class="phone_num"></span>')
          .text('(+' + phone_num + ')')
          .appendTo('#contact_phone_num_container');

        EditContactForm.$form.find('.input_button input[type=submit]').val('Изменить');

        EditContactForm
          .reset(function() {
            $target.show();
            $('#contact_phone_num_container .phone_num').remove();
            $phone_num_input.show();
          })
          .submit(function() {
            var contact_name_value = $.trim($contact_name_input.val());
            if (!contact_name_value.length) {
              $contact_name_input.val('');
              $contact_name_input.focus();
              return false;
            }

            EditContactForm.reset();

            $target.empty();

            var $contact_name_node = $('<span class="contact_name"/>');
            var $phone_num_node = $('<span class="phone_num"/>');

            $contact_name_node.text(contact_name_value).appendTo($target);
            $('<br/>').appendTo($target);
            $phone_num_node.text('(+' + phone_num + ')').appendTo($target);

            $target.show();

            sendRequest('RenameContact', [selected.anumber_id, contact_name_value]);

            $('#view_contacts').triggerHandler('activate');

            return false;
          });

        $target.hide().before(EditContactForm.$container);
        EditContactForm.show();

        $contact_name_input.val(curr_contact_name);
        $contact_name_input.focus();
      }

      else if (selected.group_id)
      {
        $target = $(ContactList.getSelectedGroup());

        RBTContacts.cancelActiveAction();

        var $group_name_input = EditGroupForm.$input('group_name');

        EditGroupForm.$form.find('.input_button input[type=submit]').val('Изменить');

        EditGroupForm
          .reset(function() {
            $target.show();
          })
          .submit(function() {
            var group_name_value = $.trim($group_name_input.val());

            if (!group_name_value.length) {
              $group_name_input.val('');
              $group_name_input.focus();
              return false;
            }

            $('#group_entry_' + selected.group_id).find('.group_title').text(group_name_value);

            sendRequest('RenameGroup', [selected.group_id, group_name_value]);

            EditGroupForm.reset();

            $('#view_contacts').triggerHandler('activate');

            return false;
          });

        $group_name_input.val($target.find('.group_title').text());

        $target.hide().before(EditGroupForm.$container);
        EditGroupForm.show();
        $group_name_input.focus();
      }

      else {
        alert('Не выбран элемент списка');
      }

      return false;
    });


  $('#delete_contact')
    .click(function()
    {
      RBTContacts.cancelActiveAction();

      var $target, operation;

      if (selected.anumber_id)
      {
        $target = $(ContactList.getSelectedItem());

        var contact_name = $.trim($target.find('.contact_name').text());

        if (!contact_name) {
          contact_name = $.trim($target.find('.phone_num').text());
        }

        var message = 'Вы действительно хотите удалить ' + ($target.closest('.group').length ? 'члена группы "' : 'абонента "') + contact_name + '"?';

        if (window.confirm(message))
        {
          $target.remove();

          operation = new SelfCare_RBTOperation('RemoveContact');

          if (selected.link_type > 1) {
            $('#rule_' + selected.link_id + '_data tr')
              .each(function(i, data_row) {
                var entry_id = $.trim($(data_row).children('.entry_id').text());
                operation.addAction('RemoveRuleItem', [entry_id]);
              });
          }

          operation.addAction('RemoveContact', [selected.anumber_id]);

          operation.commit();
        }
      }

      else if (selected.group_id)
      {
        $target = $(ContactList.getSelectedGroup());

        if (
          window.confirm('Вы действительно хотите удалить группу "' + $target.find('.group_title').text() + '"?')
        ) {
          operation = new SelfCare_RBTOperation('RemoveGroup');

          if (selected.link_type > 1) {
            $('#rule_' + selected.link_id + '_data tr')
              .each(function(i, data_row) {
                var entry_id = $.trim($(data_row).children('.entry_id').text());
                operation.addAction('RemoveRuleItem', [entry_id]);
              });
          }

          operation.addAction('RemoveGroup', [selected.group_id]);

          $target.remove();

          operation.commit();
        }
      }

      else {
        alert('Не выбран элемент списка');
      }

      return false;
    });


  this.createContact = function(phone_num, contact_name, group_id)
  {
    contact_name = contact_name || null;

    var $new_node = $('<li class="item"><a href="#"/></li>');
    var $a = $new_node.children('a');

    var $contact_name_node = $('<span class="contact_name"/>');
    var $phone_num_node = $('<span class="phone_num"/>');
    
    if (contact_name) {
      $contact_name_node.text(contact_name).appendTo($a);
      $('<br/>').appendTo($a);
      $phone_num_node.text('(' + phone_num + ')').appendTo($a);
    }
    else {
      $phone_num_node.text(phone_num).appendTo($a);
    }

    if (group_id) {
      $('#group_entry-' + group_id + ' > .contact_list').append($new_node);
      var operation = new SelfCare_RBTOperation('AddContact');
      operation.addAction('AddContact', [phone_num, contact_name]);
      operation.addAction('SetContactLink', [phone_num, '1', group_id]);
      operation.commit(function(status) {
        if (status != 'success') { return; }
        
        var $group = $('#group_entry-' + group_id);
        $group.triggerHandler('Select');

        var $phone_num = $group.find(".phone_num:contains('" + phone_num + "')");
        if ($phone_num.length) {
          $phone_num.closest('.item').triggerHandler('Select');
        }
      });
    }
    else {
      $('#ungrouped_anumbers > .contact_list').append($new_node);
      sendRequest(
        'AddContact', [phone_num, contact_name],
        function(status) {
          if (status != 'success') { return; }
          $('#ungrouped_anumbers').find(".phone_num:contains('" + phone_num + "')")
            .closest('.item').triggerHandler('Select');
        });
    }
  };


  var melody_select_change = function()
  {
    var $checkbox = $(this).closest('table').closest('tr').find('.rule_item_checkbox');

    if (!this.value.length)
      $checkbox.removeAttr('checked');
    else
      $checkbox.attr('checked', 'checked');
  };

  $('.rule_item_checkbox')
    .each(function() {
      $(this).closest('tr').find('select[name=melody_id]')
        .bind('change', melody_select_change)
        .bind('keyup', melody_select_change);
    });


  var parse_rule_type = /^rule_type_(\d+)_button/;

  $('#rule_types_menu .rule_type_button')
    .click(function() {
      var $this = $(this);
      if (!$this.hasClass('readonly') && !$this.hasClass('active')) {
        var new_type_id = parse_rule_type.exec(this.id)[1];
        var old_type_id = selected.link_type;

        if (SelfCare_changeCurrentRuleType(selected.link_id, old_type_id, new_type_id)) {
          RBTContacts.activateRuleTypeIcon(new_type_id);
          selected.link_type = old_type_id;
        }
      }
      return false;
    });


  this.addLinkToSelectedItem = function(operation, link_type, entity_id)
  {
    if (selected.group_id) {
      operation.addAction('SetGroupLink', [selected.group_id, link_type, entity_id]);
    }
    else if (selected.anumber_id) {
      operation.addAction('SetContactLink', [selected.anumber_id, link_type, entity_id]);
    }
    else {
      throw {message: 'Не выбран элемент списка', code: 1};
    }
  };

}


// [Reservation Form]
function SelfCare_ReservationForm(form_id, operation_id)
{
  this.DOMConstruct('#' + form_id);

  var form = this;

  this.submit(function()
  {
    var $StartMSISDN = $('input[name=StartMSISDN]'),
        $EndMSISDN = $('input[name=EndMSISDN]'),
        $StartMSISDNPrefix = $StartMSISDN.closest('table').find('select[name=prefix_selector]'),
        $EndMSISDNPrefix = $EndMSISDN.closest('table').find('select[name=prefix_selector]'),
        $Count = $('input[name=Count]'),
        $SubscriberTemplate = $('select[name=SubscriberTemplate]');

    var start_msisdn_val = $StartMSISDN.val(),
        end_msisdn_val = $EndMSISDN.val(),
        count_val = $Count.val();

    var short_msisdn_regex = /^\d{6}$/;

    if (!short_msisdn_regex.test(start_msisdn_val)) {
      alert('Номер введён неверно');
      $StartMSISDN.focus().select();
      return false;
    }

    if (!short_msisdn_regex.test(end_msisdn_val)) {
      alert('Номер введён неверно');
      $EndMSISDN.focus().select();
      return false;
    }

    if (start_msisdn_val > end_msisdn_val) {
      alert('Диапазон номеров задан неверно');
      $EndMSISDN.focus().select();
      return false;
    }

    if (!/^\d+$/.test(count_val)) {
      alert('Количество задано неверно');
      $Count.focus().select();
      return false;
    }

    if (count_val > 100) {
      alert('Количество не должно быть больше 100');
      $Count.focus().select();
      return false;
    }

    var params = {
      user_input_1: operation_id,
      user_input_2: $StartMSISDNPrefix.val() + start_msisdn_val,
      user_input_3: $EndMSISDNPrefix.val() + end_msisdn_val,
      user_input_4: count_val,
      user_input_6: $SubscriberTemplate.val(),
      user_input_7: operation_id
    };

    var category_checked = false;

    $('input[name=CategorySelector]')
      .each(function() {
        if (this.checked) {
          params['user_input_multi_5_' + this.value] = 'true';
          category_checked = true;
        } else {
          params['user_input_multi_5_' + this.value] = '';
        }
      });

    if (!category_checked) {
      alert('Не выбрана категория');
      $('input[name=CategorySelector]:eq(0)').focus();
      return false;
    }

    var delete_rows = [];

    switch (operation_id)
    {
      case '2': // search
        params.user_input_8 = '';
        break;
      
      case '1': // reserve
      case '0': // unreserve
        var rows_xml = '';
        
        $('input[name=net_resource_identity]', form.$form)
          .each(function() {
            if (this.checked) {
              rows_xml += '<row><columns><column>' + this.value + '</column></columns></row>';
              if (operation_id == '1') {
                delete_rows.push($(this).closest('tr').get(0));
              }
            }
          });

        if (!rows_xml.length) {
          alert('Не выбраны номера');
          return false;
        }

        params.user_input_8 = '<rows>' + rows_xml + '</rows>';
        break;
    }
    
    SelfCare.request(
      '_next', params,
      function(status, $response)
      {
        if (status != 'success') { return; }

        var $table = $response.children('table'),
            $tbody = $table.children('tbody');
        
        if ($tbody.length) {
          $('#' + $table.attr('id') + ' .table > tbody')
            .empty().append($tbody.children());

          if (delete_rows.length) {
            $(delete_rows).remove();
            if ($table.attr('id') != 'available_net_resource') {
              (new SelfCare_TableRowsPaging('#available_net_resource .table', rows_per_page));
            }
          }

          (new SelfCare_TableRowsPaging('#' + $table.attr('id') + ' .table', rows_per_page));

          var $curr_table = $('#' + form_id + ' .table'),
              check_all = $curr_table.children('thead').children('tr').children('th:eq(0)').children('input').get(0);

          if (check_all && check_all.checked)
          {
            var has_enabled = false,
                has_unchecked = false;
            
            $curr_table.children('tbody').children('tr').children('td:first-child').children('input')
              .each(function() {
                if (!this.disabled) {
                  has_enabled = true;
                  if (!this.checked) {
                    has_unchecked = true;
                    return false;
                  }
                }
              });

            if (!has_enabled || has_unchecked) {
              check_all.checked = false;
            }
          }
        }
      });

    return false;
  });
}
SelfCare_ReservationForm.prototype = new SelfCare_Form;


function SelfCare_TableRowsPaging(table, rows_per_page, custom_map)
{
  var $table = $(table),
      $rows, $checkboxes, $paging, $check_all;

  if (typeof custom_map == 'undefined') {
    $rows = $table.children('tbody').children('tr');
    $checkboxes = $table.children('tbody').children('tr').find('> td:first-child > input');
    $paging = $table.find('> tfoot > tr > .paging');
    $check_all = $table.find('> thead > tr > th:eq(0) > input');
  }
  else {
    $rows = custom_map.$rows;
    $checkboxes = custom_map.$checkboxes;
    $paging = custom_map.$paging;
    $check_all = custom_map.$check_all;
  }
  
  var $active_page = $paging.children('.active'),
      active_page = $active_page.length ? parseInt($active_page.text(), 10) : 1;

  $paging.empty();

  var $visible_rows = $rows.filter(':not(.invisible)').filter(':not(.invisible2)');
  
  var pages = Math.ceil($visible_rows.length / rows_per_page);

  if (active_page > pages) {
    active_page = pages;
  }
  
  var PageClick = function()
  {
    var $this = $(this),
        page = $this.text();

    $visible_rows.filter(':visible').hide();
    $this.siblings('.active').removeClass('active');

    var start = rows_per_page * (page - 1),
        end = start + rows_per_page;

    $visible_rows.slice(start, end).show();

    $this.addClass('active');

    return false;
  };
  
  for (var i = 1; i <= pages; i++)
  {
    var $a = $('<a href="#" class="page_button"/>')
        .text(i)
        .click(PageClick)
        .appendTo($paging);

    if (i == active_page) {
      $a.addClass('active');
    }
  }

  if ($check_all.length)
  {
    if (!$visible_rows.length) {
      $check_all.attr('disabled', true);
    }
    else
    {
      var has_enabled_rows = false;

      $checkboxes
        .each(function() {
          if (!this.disabled) {
            has_enabled_rows = true;
            return false;
          }
        });

      $check_all.attr('disabled', !has_enabled_rows);
    }
  }

  $rows.hide();
  
  $visible_rows.slice(0, rows_per_page).show();
}

// [Attachment Form]
function SelfCare_AttachmentForm()
{
  this.DOMConstruct('#attachment_form');

  var form = this;

  this.submit(function()
  {
    var start_val = form.$input('StartDate').val(),
        end_val = form.$input('EndDate').val(),
        start_a = SelfCare_date_format_regex.exec(start_val),
        end_a = SelfCare_date_format_regex.exec(end_val);

    if (!start_a || !end_a)
    {
      alert('Неверный формат даты');
      if (!start_a) {
        form.$input('StartDate').focus().select();
      }
      else if (!end_a) {
        form.$input('EndDate').focus().select();
      }
      return false;
    }

    var start_time = (new Date(start_a[4], start_a[3] - 1, start_a[2], 0, 0, 0)).getTime(),
        end_time = (new Date(end_a[4], end_a[3] - 1, end_a[2], 23, 59, 59)).getTime();

    if (start_time >= end_time) {
      alert('Неверно задан временной интервал');
      form.$input('EndDate').focus().select();
      return false;
    }

    /*var max_range_time = (14 * (24 * 60 * 60)) * 1000;
    
    if ((end_time - start_time) > max_range_time) {
      alert('Просмотр статистики возможен только за период не более двух недель');
      form.$input('EndDate').focus().select();
      return false;
    }*/
    
    var params = {
      user_input_1: 'content',
      user_input_2: start_val,
      user_input_3: end_val
    };

    SelfCare.request('_next', params);

    return false;
  });
}
SelfCare_AttachmentForm.prototype = new SelfCare_Form;


function SelfCare_AttachmentTypeFolders()
{
  var FolderList = new GroupedListControl('#attachment_type_folders');

  if (FolderList.$groups) {
    FolderList.$groups
      .bind('Select', function() {
        var parsed = /link-(\d+)/.exec(this.className);
        $('#contract_attachment_table > tbody > tr').hide().addClass('invisible');
        $('#contract_attachment_table > tbody > .link-' + parsed[1]).removeClass('invisible').slice(0, rows_per_page).show();
      
        new SelfCare_TableRowsPaging('#contract_attachment_table', 10);
      });
  }

  if (FolderList.$items) {
    FolderList.$items
      .bind('Select', function() {
        var parsed = /link-(\d+)-(\d+)/.exec(this.className);
        $('#contract_attachment_table > tbody > tr').hide().addClass('invisible');
        $('#contract_attachment_table > tbody > .link-' + parsed[1] + '-' + parsed[2]).removeClass('invisible').slice(0, rows_per_page).show();
        
        new SelfCare_TableRowsPaging('#contract_attachment_table', rows_per_page);
      });
  }
}



// [Statistic Form]
function SelfCare_StatisticForm()
{
  this.DOMConstruct('#statistic_form');

  this.$input('StatisticType').attr('disabled', 'disabled');

  DrawStatisticGraphics();

  var form = this;

  this.submit(function()
  {
    var $StatisticType = form.$input('StatisticType'),
        start_val = form.$input('StartDate').val(),
        end_val = form.$input('EndDate').val(),
        start_a = SelfCare_date_format_regex.exec(start_val),
        end_a = SelfCare_date_format_regex.exec(end_val);

    if (!start_a || !end_a)
    {
      alert('Неверный формат даты');
      if (!start_a) {
        form.$input('StartDate').focus().select();
      }
      else if (!end_a) {
        form.$input('EndDate').focus().select();
      }
      return false;
    }

    var start_time = (new Date(start_a[4], start_a[3] - 1, start_a[2], 0, 0, 0)).getTime(),
        end_time = (new Date(end_a[4], end_a[3] - 1, end_a[2], 23, 59, 59)).getTime();

    if (start_time >= end_time) {
      alert('Неверно задан временной интервал');
      form.$input('EndDate').focus().select();
      return false;
    }

    var max_range_time = (31 * (24 * 60 * 60)) * 1000;

    if ((end_time - start_time) > max_range_time) {
      alert('Просмотр статистики возможен только за период не более одного месяца');
      form.$input('EndDate').focus().select();
      return false;
    }

    var sys_date_val = $('#SysDate').text(),
        sys_date_a = SelfCare_date_format_regex.exec(sys_date_val),
        sys_date_time = (new Date(sys_date_a[4], sys_date_a[3] - 1, sys_date_a[2], 23, 59, 59)).getTime();

    if (end_time >= sys_date_time) {
      alert('Просмотр статистики возможен только за прошедший период');
      form.$input('EndDate').focus().select();
      return false;
    }

    var signing_date_val = $('#SigningDate').text(),
        signing_date_a = SelfCare_date_format_regex.exec(signing_date_val),
        signing_date_time = (new Date(signing_date_a[4], signing_date_a[3] - 1, signing_date_a[2], 0, 0, 0)).getTime();

    if (start_time < signing_date_time) {
      alert('Просмотр статистики возможен только за послерегистрационный период (' + signing_date_val + ')');
      form.$input('StartDate').focus().select();
      return false;
    }

    SelfCare.request('_next', [$StatisticType.val(), start_val, end_val], 'content');

    return false;
  });
}
SelfCare_StatisticForm.prototype = new SelfCare_Form;



function DrawStatisticGraphics()
{
  var $data_table = $('#DailyStatisticData');

  var dollar_soms = 43; // TODO: Get Dollar Course

  var data_total_subscriber = [],
      data_active_subscriber = [],
      data_total_charged_arpu = [],
      data_total_billed_arpu = [];

  $data_table.children('tbody').children('tr')
    .each(function() {
      var time_and_zone = $(this).children('.TIME_AND_ZONE').text(),
          active_subscriber_base = parseInt($(this).children('.ACTIVE_SUBSCRIBER_BASE').text(), 10),
          total_subscriber_base = parseInt($(this).children('.TOTAL_SUBSCRIBER_BASE').text(), 10),
          total_charged = Math.ceil(parseInt($(this).children('.TOTAL_CHARGED').text(), 10) / active_subscriber_base / dollar_soms * 100) / 100,
          total_billed = Math.ceil(parseInt($(this).children('.TOTAL_BILLED').text(), 10) / active_subscriber_base / dollar_soms * 100) / 100;

      data_total_subscriber.push([time_and_zone, total_subscriber_base]);
      data_active_subscriber.push([time_and_zone, active_subscriber_base]);
      data_total_charged_arpu.push([time_and_zone, total_charged, '$' + total_charged]);
      data_total_billed_arpu.push([time_and_zone, total_billed, '$' + total_billed]);
    });

  $.jqplot('chart_subscriber_base', [data_total_subscriber, data_active_subscriber], {
    title: 'Абонентская база',
    legend: {show: true, location: 'nw'},
    axes: {
      xaxis: {
        renderer: $.jqplot.DateAxisRenderer,
        tickOptions: {formatString: '%d.%m.%Y'}
      },
      yaxis: {
        min: 0,
        tickOptions: {formatString: '%d'}
      }
    },
    seriesDefaults: {
        showMarker: true,
        lineWidth: 3,
        pointLabels: {
          location: 's',
          ypadding: 3
        }
    },
    series: [
      {label: 'Общая абонентская база'},
      {label: 'Из них активно'}
    ]
  });

  $.jqplot('chart_subscriber_arpu', [data_total_charged_arpu, data_total_billed_arpu], {
    title: 'Среднедневные начисления на одного активного абонента',
    legend: {show: true, location: 'nw'},
    axes: {
      xaxis: {
        renderer: $.jqplot.DateAxisRenderer,
        tickOptions: {formatString: '%d.%m.%Y'}
      },
      yaxis: {
        min: 0,
        tickOptions: {formatString: '$%.2f'}
      }
    },
        seriesDefaults: {
        showMarker: true,
        lineWidth: 3,
        pointLabels: {
          location: 's',
          ypadding: 3
        }
    },
    series: [
      {label: 'Общие начисления'},
      {label: 'Из них фактуруемо'}
    ]
  });
}



function SelfCare_PauseFormSubscriberTemplateFilter()
{
  var $filter_container = $('#subscriber_template_filter');
  var $filter_checkboxes = $filter_container.children('li').children('.filter_include');

  $filter_checkboxes
    .bind('click', function()
    {
      var link_id = /link-(\d+)/.exec(this.parentNode.className)[1];
      var $member_rows = $('#contract_available_member > form > .table > tbody > .link-' + link_id);
      var check_all = $filter_container.children('li:eq(0)').children('label').children('input.check_all').get(0);

      if (this.checked)
      {
        var all_checked = true;

        $filter_checkboxes
          .each(function() {
            if (!this.checked) { return all_checked = false; }
          });

        check_all.checked = all_checked;

        $member_rows.removeClass('invisible').filter(':not(.invisible2)')
          .find('input[name=msisdn]').attr('disabled', false);
        
        $(this.parentNode).addClass('item-selected');
      }
      else
      {
        check_all.checked = false;
        
        $member_rows.addClass('invisible')
          .find('input[name=msisdn]').attr('disabled', true);

        $(this.parentNode).removeClass('item-selected');
      }
      
      new SelfCare_TableRowsPaging('#contract_available_member > form > table', rows_per_page);
      
      $('#contract_available_member input[name=msisdn]:not(:disabled)').eq(0).triggerHandler('click');
    });
  
  $filter_container.children('.item').children('a')
    .bind('click', function() {
      var $checkbox = $(this).prev('input');
      $checkbox.attr('checked', !$checkbox.get(0).checked);
      $checkbox.triggerHandler('click');
      return false;
    });

  var SearchForm = new SelfCare_SearchForm('#member_search', 'Поиск');
  var $search = SearchForm.$input('search_phrase');
  var curr_value = '';

  var doSearch = function()
  {
    var search_val = $.trim($search.val());

    if (curr_value != search_val)
    {
      curr_value = search_val;
      
      $('#contract_available_member > form > table > tbody > tr')
        .each(function()
        {
          var $trow = $(this),
              $checkbox = $trow.find('> td:first > input[name=msisdn]');

          if ($trow.is(":contains('" + StringUtilities.addSlashes(search_val) + "')"))
          {
            $trow.removeClass('invisible2');
            if (!$trow.hasClass('invisible')) {
              $checkbox.attr('disabled', false);
            }
          }
          else
          {
            $trow.addClass('invisible2');
            if (!$trow.hasClass('invisible')) {
              $checkbox.attr('disabled', true);
            }
          }
        });
      
      new SelfCare_TableRowsPaging('#contract_available_member > form > table', rows_per_page);

      $('#contract_available_member input[name=msisdn]:not(:disabled)').eq(0).triggerHandler('click');
    }
  };

  var keyup_timeout = null;

  $search.bind('keyup', function()
  {
    if (keyup_timeout) {
      clearTimeout(keyup_timeout);
      keyup_timeout = null;
    }

    keyup_timeout = setTimeout(doSearch, 500);
  });

  SearchForm.submit(function()
  {
    if (keyup_timeout) {
      clearTimeout(keyup_timeout);
      keyup_timeout = null;
    }
    
    doSearch();
  });

  this.doSearch = function() {
    doSearch();
  };
}


function SelfCare_PauseForm_AvailableMembers()
{
  var $member_table = $('#contract_available_member > form > table'),
      $member_checkboxes = $member_table.find('> tbody > tr > td:first-child > input[name=msisdn]'),
      check_all = $member_table.find('thead > tr:first > th:first > input.check_all').get(0);

  $member_checkboxes
    .bind('click', function()
    {
      $(this.parentNode).siblings(':last').find('input[type=radio]').attr('disabled', !this.checked);

      $('#unpause_button').attr('disabled', true)
        .closest('table').addClass('disabled');

      var blocked_checked_count = $('#contract_blocked_member > form > ul > .item input[name=msisdn]:checked').length;

      if (this.checked)
      {
        var all_checked = true,
            has_enabled_rows = false;

        $member_checkboxes
          .each(function() {
            if (!this.disabled) {
              has_enabled_rows = true;
              if (!this.checked) {
                all_checked = false;
              }
            }
          });

        check_all.checked = (has_enabled_rows && all_checked);
        
        if (blocked_checked_count == 0) {
          $('#pause_button').attr('disabled', false)
            .closest('table').removeClass('disabled');
        }
        else {
          $('#pause_button').attr('disabled', true)
            .closest('table').addClass('disabled');
        }

        $('#retreive_button').attr('disabled', false)
          .closest('table').removeClass('disabled');
      }
      else {
        check_all.checked = false;

        if ($member_checkboxes.filter(':not(:disabled)').filter(':checked').length != 0)
        {
          $('#retreive_button').attr('disabled', false)
            .closest('table').removeClass('disabled');

          if (blocked_checked_count == 0) {
            $('#pause_button').attr('disabled', false)
              .closest('table').removeClass('disabled');
          }
          else {
            $('#pause_button').attr('disabled', true)
              .closest('table').addClass('disabled');
          }
        }
        else {
          $('#pause_button').attr('disabled', true)
            .closest('table').addClass('disabled');

          if (blocked_checked_count != 0) {
            $('#retreive_button').attr('disabled', false)
              .closest('table').removeClass('disabled');
          }
          else {
            $('#retreive_button').attr('disabled', true)
              .closest('table').addClass('disabled');
          }
        }
      }
    });

  $member_table.find('.subscriber_name')
    .click(function() {
      var $checkbox = $(this).closest('tr').find('> td:first-child > input[name=msisdn]');
      $checkbox.attr('checked', !$checkbox.get(0).checked).triggerHandler('click');
    });

  new SelfCare_TableRowsPaging($member_table.get(0), rows_per_page);
}


function SelfCare_PauseForm_BlockedMembers()
{
  var $blocked_container = $('#contract_blocked_member > form > .list'),
      $blocked_checkboxes = $blocked_container.children('.item').find('input[name=msisdn]'),
      check_all = $blocked_container.find('> li:first > label > input.check_all').get(0);

  $blocked_checkboxes
    .bind('click', function()
    {
      $('#pause_button').attr('disabled', true)
        .closest('table').addClass('disabled');

      var available_checked_count = $('#contract_available_member > form > table > tbody > tr > td:first-child > input[name=msisdn]:not(:disabled)').filter(':checked').length;
      
      if (this.checked)
      {
        var all_checked = true,
            has_enabled_rows = false;

        $blocked_checkboxes
          .each(function() {
            if (!this.disabled) {
              has_enabled_rows = true;
              if (!this.checked) {
                all_checked = false;
              }
            }
          });

        check_all.checked = (has_enabled_rows && all_checked);

        $(this.parentNode.parentNode).addClass('item-selected');

        if (available_checked_count == 0) {
          $('#unpause_button').attr('disabled', false)
            .closest('table').removeClass('disabled');
        }
        else {
          $('#unpause_button').attr('disabled', true)
            .closest('table').addClass('disabled');
        }

        $('#retreive_button').attr('disabled', false)
          .closest('table').removeClass('disabled');
      }
      else {
        check_all.checked = false;
        $(this.parentNode.parentNode).removeClass('item-selected');

        if ($blocked_checkboxes.filter(':checked').length != 0)
        {
          $('#retreive_button').attr('disabled', false)
            .closest('table').removeClass('disabled');

          if (available_checked_count == 0) {
            $('#unpause_button').attr('disabled', false)
              .closest('table').removeClass('disabled');
          }
          else {
            $('#unpause_button').attr('disabled', true)
              .closest('table').addClass('disabled');
          }
        }
        else {
          $('#unpause_button').attr('disabled', true)
            .closest('table').addClass('disabled');

          if (available_checked_count != 0) {
            $('#retreive_button').attr('disabled', false)
              .closest('table').removeClass('disabled');
          }
          else {
            $('#retreive_button').attr('disabled', true)
              .closest('table').addClass('disabled');
          }
        }
      }
    });

  $blocked_container.children('.item').children('a')
    .bind('click', function() {
      var $checkbox = $(this).prev('div').children('input');
      $checkbox.attr('checked', !$checkbox.get(0).checked);
      $checkbox.triggerHandler('click');
      return false;
    });

  new SelfCare_TableRowsPaging($blocked_container.get(0), 5, {
        $rows: $blocked_container.children('.item'),
        $checkboxes: $blocked_container.find('input[name=msisdn]'),
        $paging: $blocked_container.children('.paging'),
        $check_all: $blocked_container.children('.check_all_items').children('label').children('.check_all')
      });
}


function SelfCare_createTableForm(container, column_headers)
{
  var $form = $('<form action="#" onsubmit="return false;">' +
                  '<table class="table no_borders" cellspacing="0">' +
                    '<thead></thead>' +
                    '<tbody></tbody>' +
                    '<tfoot></tfoot>' +
                  '</table>' +
                '</form>').appendTo(container);

  if (typeof column_headers != 'undefined') {
    var $thead_row = $('<tr/>').appendTo($form.find('> table > thead'));
    for (var i = 0, text; text = column_headers[i]; i++)
    {
      var $tcol = $('<th/>');
      if (typeof text == 'string' && text[0] != '<')
      {
        switch(text) {
          case '[v]':
              $tcol.addClass('checkbox_container')
                .append('<input type="checkbox" class="check_all" checked="checked"/>');
            break;

          default:
            $tcol.text(text);
            break;
        }
      } else {
        $tcol.append(text);
      }
      $tcol.appendTo($thead_row.get(0));
    }
  }

  return $form;
}


function SelfCare_MSISDNRetrieveForm(msisdn_list)
{
  var msisdn_per_page = 5;

  var $container = $('<div id="msisdn_retreive_form"/>'),
      $form = SelfCare_createTableForm($container.get(0), ['[v]', 'Абонент', 'Секретный код пакета']),
      $table = $form.children('table'),
      $tbody = $table.children('tbody'),
      $tfoot = $table.children('tfoot'),
      check_all = $table.find('> thead > tr > th:first > .check_all').get(0),
      msisdn_pin_inputs = {};

  var checkboxClick = function()
  {
    var $trow = $(this).closest('tr');

    if (!this.checked) {
      $trow.addClass('disabled');
      check_all.checked = false;
    }
    else {
      $trow.removeClass('disabled');
      var $checkbox_list = $tbody.find('> tr > td:first-child > input');
      check_all.checked = ($checkbox_list.length == $checkbox_list.filter(':checked').length);
    }
  },
  checkboxChange = function() { $(this).triggerHandler('click'); };

  var i = 0, msisdn;

  for (msisdn in msisdn_list)
  {
    var format_msisdn = '+' + msisdn;
    
    var $trow = $('<tr/>').attr('id', 'retreive_msisdn-' + msisdn);
    if (i >= msisdn_per_page) {
      $trow.css('display', 'none');
    }

    $trow.appendTo($tbody.get(0));

    $('<td class="checkbox_container"/>')
        .appendTo($trow.get(0))
        .append(
          $('<input type="checkbox" value="' + msisdn + '" checked="checked"/>')
              .click(checkboxClick)
              .change(checkboxChange)
            .get(0)
        );
    
    $('<td/>')
        .append(msisdn_list[msisdn])
        .append('<br/><span class="msisdn">' + format_msisdn + '</span>')
        .appendTo($trow.get(0));

    msisdn_pin_inputs[msisdn] =
        $('<td class="pin_input_container"/>')
            .append(SelfCare_CreateInput({
              type: 'text',
              name: 'retreive_pin',
              title: 'PIN восстановления для номера ' + format_msisdn
            }))
            .appendTo($trow.get(0))
            .find('input[name=retreive_pin]').get(0);

    i++;
  }
  
  this.DOMConstruct($container.get(0));

  $('<tr><td colspan="3" class="paging"/></tr>')
      .appendTo($tfoot.get(0)).children('td');

  var $tfoot_cell = $('<tr><td colspan="3" class="selected"/></tr>')
                      .appendTo($tfoot.get(0)).children('td');

  $tfoot_cell.append('<div class="float_left"/>')
      .children('div').append(SelfCare_CreateButton('Восстановить', 'submit'));

  new SelfCare_TableRowsPaging($table.get(0), msisdn_per_page);

  this.submit(function()
  {
    var pin_regex = /^\d{5}$/,
        rows_xml = '',
        pin_values_msisdn = {};
    
    for (var msisdn in msisdn_pin_inputs)
    {
      var $input = $(msisdn_pin_inputs[msisdn]);
      if ($input.closest('table').closest('tr').hasClass('disabled')) {
        continue;
      }
      
      var pin_value = $.trim($input.val());
      
      if (!pin_value.length) {
        alert(($tbody.children('tr').length == 1) ? 'Введите PIN восстановления' : 'Введите ' + $input.attr('title'));
        $input.val('').focus();
        return false;
      }
      
      else if (!pin_regex.test(pin_value)) {
        alert(($tbody.children('tr').length == 1) ? 'Неверно введён PIN восстановления' : 'Неверно введён ' + $input.attr('title'));
        $input.focus().select();
        return false;
      }

      else if (typeof pin_values_msisdn[pin_value] != 'undefined') {
        alert('Введены два или более одинаковых PIN');
        highlightErrorRow($input.closest('table').closest('tr'));
        highlightErrorRow($('#retreive_msisdn-' + pin_values_msisdn[pin_value]));
        return false;
      }

      else {
        pin_values_msisdn[pin_value] = msisdn;
        rows_xml += '<row><columns><column>' + msisdn + '</column><column>' + pin_value + '</column></columns></row>';
      }
    }

    $tbody.find('> tr > td:last-child > .error').remove();

    SelfCare.request(
        '_next', ['2', '<rows>' + rows_xml + '</rows>'], 'content',
        function(status, $response) {
          if (status != 'success') { return; }
          
          var $op_notification = $response.children('#OperationNotification');
          if ($op_notification.length) {
            var msg_entry_list = $op_notification.text().split(';');
            for (var i = 0, entry, a; entry = msg_entry_list[i]; i++) {
              a = entry.split(' - ');
              $('<span class="error"/>').text($.trim(a[1]))
                .appendTo($('#retreive_msisdn-' + $.trim(a[0]) + ' > td:last-child'));
            }
          }
          else {
            SelfCare.loadResponse($response, 'content');
          }
        }, true);
    
    return false;
  });

  SelfCare_CreateButton('Отмена', 'button')
      .appendTo($tfoot_cell.get(0)).after('<div class="clear"/>')
      .find('input[type=button]')
        .click(function() { window.PageShader.hide(); });

  window.PageShader.show($container, 500, 280)
    .onhide(function() {
      $container.remove();
    });
}
SelfCare_MSISDNRetrieveForm.prototype = new SelfCare_Form;


function SelfCare_buildMSISDNRetrieveForm()
{
  var msisdn_list = {},
      msisdn_list_length = 0;

  $('#contract_available_member input[name=msisdn]:checked').filter(':not(:disabled)')
    .each(function() {
      var $trow = $(this).closest('tr');
      msisdn_list[$trow.find('input[type=radio]:checked').val()] = $trow.children('td:eq(1)').children(':first').clone().get(0);
      msisdn_list_length++;
    });

  $('#contract_blocked_member input[name=msisdn]:checked').filter(':not(:disabled)')
    .each(function() {
      var $item = $(this).closest('li');
      msisdn_list[this.value] = $item.children('a:first').children(':first').clone().get(0);
      msisdn_list_length++;
    });

  if (!msisdn_list_length) {
    alert('Не выбраны номера');
  }
  else {
    new SelfCare_MSISDNRetrieveForm(msisdn_list);
  }
}



// [Pause Form]
function SelfCare_PauseForm(container, operation_id)
{
  this.DOMConstruct(container);

  var $entries_container = this.$form.children('.list, .table');

  switch (operation_id) {
    case 1: // pause
      SelfCare_PauseForm_AvailableMembers();
      break;

    case 0: // unpause
      SelfCare_PauseForm_BlockedMembers();
      break;
  }
  
  var form = this;

  this.submit(function()
  {
    var getRowValue,
        rows_xml = '',
        operate_rows = [];
    
    switch (operation_id) {
      case 1: // pause
        $('#pause_button').attr('disabled', true)
          .closest('table').addClass('disabled');
        
        getRowValue = function(checkbox) {
          var $row = $(checkbox).closest('tr');
          rows_xml += '<row><columns><column>' + ($row.find('input[type=radio]:checked').val()) + '</column></columns></row>';
          operate_rows.push($row.get(0));
        };
        break;

      case 0: // unpause
        $('#unpause_button').attr('disabled', true)
          .closest('table').addClass('disabled');

        getRowValue = function(checkbox) {
          rows_xml += '<row><columns><column>' + checkbox.value + '</column></columns></row>';
          operate_rows.push($(checkbox).closest('.item').get(0));
        };
        break;
    }

    $('input[name=msisdn]:not(:disabled)', form.$form)
      .filter(':checked')
        .each(function() {
          return getRowValue(this);
        });

    if (!rows_xml.length) {
      alert('Не выбраны номера');
      return false;
    }

    var params = [operation_id.toString(), '<rows>' + rows_xml + '</rows>'];

    SelfCare.request(
      '_next', params,
      operation_id.toString(),
      function(status, $response)
      {
        if (status != 'success') { return; }
        
        $(operate_rows).remove();

        var $data = $response.children('table, ul'),
            target_container_id = $data.attr('id');
        
        switch (operation_id) {
          case 1: // pause

            new SelfCare_TableRowsPaging($entries_container.get(0), rows_per_page);

            var $check_all_container = $data.children('.check_all_items'),
                $items = $data.children('.item'),
                $paging = $data.children('.paging');

            $('#' + target_container_id + ' > form > ul').empty()
              .append($check_all_container)
              .append($items)
              .append($paging);

            if ($items.filter(':not(.empty)').length != 0)
            {
              SelfCare_PauseForm_BlockedMembers();

              $('#' + target_container_id).closest('tr').show()
                .prev('tr').show();
            }
            else {
              $('#' + target_container_id).closest('tr').hide()
                .prev('tr').hide();
            }

            break;

          case 0: // unpause

            var $rows = $entries_container.children('.item');
            
            new SelfCare_TableRowsPaging($entries_container.get(0), rows_per_page, {
                  $rows: $rows,
                  $checkboxes: $rows.find('> div:first-child > input'),
                  $paging: $entries_container.children('.paging'),
                  $check_all: $entries_container.children('.check_all_items').find('input')
                });

            var $target_table = $('#' + target_container_id + ' > form > table');

            $target_table.children('tbody')
              .empty().append($data.children('tbody').children('tr'));

            SelfCare_PauseForm_AvailableMembers();

            if (!$entries_container.children('.item').length) {
              $entries_container.closest('tr').hide()
                .prev('tr').hide();
            }

            $('#member_search input[name=search_phrase]').val('').blur();

            break;
        }
      });

    return false;
  });
}
SelfCare_PauseForm.prototype = new SelfCare_Form;



function SelfCare_ContractForm(container)
{
  this.DOMConstruct(container);

  this.getFileUploadWin = function() {
    return $('#file_upload_iframe').get(0).contentWindow;
  };

  var form = this;

  this.$input('AuthenticationInstrumentType')
      .bind('change', function() {
        form.getFileUploadWin().SelfCare_changeDocumentType(this.value);
      });
  
  var date_inputs = ['EmmisionDate', 'ExpiryDate', 'DateOfBirth'];

  var i = 0, len = date_inputs.length;
  for (; i < len; i++) {
    this.$input(date_inputs[i]).setOnEmptyValueLabel('ДД.ММ.ГГГГ');
  }
  
  this.submit(function()
  {
    var inputs = ['LastName', 'FirstName', 'PatronymicName',
                  'AuthenticationInstrumentType', 'Series', 'NumericalSequence', 'Emmitor',
                  'EmmisionDate', 'ExpiryDate', 'DateOfBirth',
                  'Address', 'DeFactoAddress', 'CodeWord', 'CellPhone', 'EMail'];
    
    var i = 0, name, $input, val,
        params = [];
    
    for (; name = inputs[i]; i++)
    {
      $input = form.$input(name);
      val = $.trim($input.val());

      if (!val.length) {
        alert('Все поля обязательны для заполнения');
        $input.val('').focus();
        return false;
      }

      params[i] = val;
    }
    
    if (!form.getFileUploadWin().SelfCare_all_files_loaded) {
      alert('Не предоставлены все требуемые копии документов');
      return false;
    }

    SelfCare.request('_root/6/1', [], 'jumpTo', function() {
      window.setTimeout(function() {
        SelfCare.request('_next', params, 'content');
      }, 100);
    }, true);

    return false;
  });
}
SelfCare_ContractForm.prototype = new SelfCare_Form;



function SelfCare_MoneyTransferForm(container)
{
  this.DOMConstruct(container);

  var form = this;
  
  this.submit(function(event, operation_id)
  {
    operation_id = operation_id || 1;
    
    var $msisdn = form.$input('SubscriberMSISDN'),
        msisdn_val = $.trim($msisdn.val());

    if (!msisdn_val.length) {
      $msisdn.val('').focus();
      return false;
    }
    else if (!SelfCare_RegEx.msisdn.test(msisdn_val)) {
      alert('Неверный номер телефона');
      return false;
    }
    
    var $amount = form.$input('Amount'),
        amount_val = $.trim($amount.val());
    
    if (!amount_val.length) {
      $amount.val('').focus();
      return false;
    }
    
    SelfCare.request('_next', [operation_id.toString(), msisdn_val, amount_val], 'content');

    return false;
  });
}
SelfCare_MoneyTransferForm.prototype = new SelfCare_Form;



function SelfCare_getValidDateRangeEntry($StartDate, $EndDate, options)
{
  options = options || {};
  
  var start_val = $.trim($StartDate.val()),
      end_val = $.trim($EndDate.val()),
      start_a = SelfCare_date_format_regex.exec(start_val),
      end_a = SelfCare_date_format_regex.exec(end_val);

  if (!start_a || !end_a)
  {
    alert('Неверный формат даты');
    if (!start_a) {
      $StartDate.focus().select();
    }
    else if (!end_a) {
      $EndDate.focus().select();
    }
    return false;
  }

  var start_time = (new Date(start_a[4], start_a[3] - 1, start_a[2], 0, 0, 0)).getTime(),
      end_time = (new Date(end_a[4], end_a[3] - 1, end_a[2], 23, 59, 59)).getTime();

  if (start_time >= end_time) {
    alert('Неверно задан временной интервал');
    $EndDate.focus().select();
    return false;
  }

  var max_range_time = 0;
  
  if (typeof options.max_range_sec != 'undefined') {
    max_range_time = options.max_range_sec * 1000;
  }
  else if (typeof options.max_range_days) {
    max_range_time = options.max_range_days * 86400000;
  }
  
  if (max_range_time && (end_time - start_time) > max_range_time) {
    alert(options.max_range_exceed_error);
    $EndDate.focus().select();
    return false;
  }
  
  return [start_val, end_val];
}


function SelfCare_MoneyTransferStatisticForm(container)
{
  this.DOMConstruct(container);

  var form = this;

  this.submit(function()
  {
    var params =
        SelfCare_getValidDateRangeEntry(
          form.$input('StartDate'),
          form.$input('EndDate'), {
            max_range_days: 14,
            max_range_exceed_error: 'Просмотр статистики возможен только за период не более двух недель'
          });

    if (params != false) {
      SelfCare.request('_next', params, 'content');
    }

    return false;
  });
}
SelfCare_MoneyTransferStatisticForm.prototype = new SelfCare_Form;


function SelfCare_ShortMessageBroadcast(undefined) {
  this.DOMConstruct("#ShortMessageBroadcast");

  $("#client-subscribers-container .check_all").trigger("click");

  $(".client-group-checkbox").click(function() {
    $(".template-" + this.value).attr("checked", this.checked);
  });
  
  if ($("#start-broadcasting-button").is(":disabled")) {
    $("#client-subscribers-container input[type=checkbox]").attr("disabled", true);

    this.$input("Message").$input
      .attr("readonly", true)
      .val("Вы более не можете производить рассылки по вашей корпоративной группе");

    $("#message-bytes-counter").text("0");
    
    return;
  }

  var shortMessageBytesLimit = 135;
  var symbolLimitExceeded = false;
  
  var $counter = $("#message-bytes-counter");
  
  this.$input("Message")
    .bind("keyup", function() {
      var bytesAvailable = (shortMessageBytesLimit - StringUtilities.countBytes(this.value));
    
      if (bytesAvailable < 0) {
        if (!symbolLimitExceeded) {
          $counter.css({
            borderColor:     "#DF0000",
            backgroundColor: "#FFF7F7",
            color:           "#9F0000"
          });
          symbolLimitExceeded = true;
        }
      }
      else if (symbolLimitExceeded) {
        $counter.css({color: "", borderColor: "", backgroundColor: ""});
        symbolLimitExceeded = false;
      }
    
      $counter.text(bytesAvailable.toString(10));
    });
  
  this.submit(function() {
    // getting checked subscribers
    var $checked = $("#client-subscribers-container .client-subscriber-checkbox:checked");
    if ($checked.length == 0) {
      alert("Абоненты не отмечены");
      $("#client-subscribers-container .check_all").focus();
      return false;
    }
    
    // getting short message text
    var $message = $("#short-message-textarea");
    var message = $.trim($message.val());

    if (message.length == 0) {
      alert("Введите текст сообщения");
      $message.focus();
      return false;
    }
    
    if (StringUtilities.countBytes(message) > shortMessageBytesLimit) {
      alert("Максимальный размер SMS-сообщения - 160 символов");
      $message.focus();
      return false;
    }
    
    var ids = [];
    $checked.each(function(i) {
      ids[i] = this.value;
    });

    // building SLR params
    var params = {
      user_input_1: "content",
      user_input_2: message,
      user_input_3: $checked.length,
      user_input_4: ids.join(",")
    };
    
    // sending request
    SelfCare.request("_next", params);
    
    return false;
  });
  
  this.$input("Message").$input.triggerHandler("keyup");
}
SelfCare_ShortMessageBroadcast.prototype = new SelfCare_Form;

$(function() { SelfCare.request(); });

