SOC_NETWORK = typeof(SOC_NETWORK) != 'undefined' ? SOC_NETWORK : {};

$.extend(SOC_NETWORK,
    function () {
      function NotLoggedError() {Error.apply(this, arguments);}
      NotLoggedError.prototype = new Error();
      NotLoggedError.prototype.name = 'NotLoggedError';

      function showErrorMessage(msg) {
        alert(SOC_NETWORK.ERROR_MSG + ": " + msg);
      }

      function doRedirect(url) {
        try
        {
          window.location.href = url;
        }
        catch (e)
        {
          window.location.href = SOC_NETWORK.BASE_URL + '/';
        }
      }

      function openUrlWinAtScreenCenter(url, options)
      {
        var winOpts = '';
        if (options) {
          var reminder = 0;
          if (options.width) {
            var left = (screen.width - options.width);
            reminder = left % 2;
            left = (left - reminder) / 2;

            winOpts += 'left=' + left + 'px, width=' + options.width + 'px';
          }

          if (options.height) {
            if (winOpts != '')
              winOpts += ',';

            var top = (screen.height - options.height);
            reminder = top % 2;
            top = (top - reminder) / 2;

            winOpts += 'top=' + top + 'px, height=' + options.height + 'px';
          }
        }

        var windowOpts = 'directories=no, status=no, scrollbars=yes, resizable=yes';
        if (options.windowOpts)
          windowOpts = options.windowOpts;

        if (windowOpts.length > 0)
          windowOpts = ', ' + windowOpts;

        var opts = winOpts + windowOpts;
        window.open(url, '_blank', opts);
      }

      function loggedCheck(loginDialog, func, options) {
        var doLogin = true;
        try
        {
          var ret = func();

          if (ret.status == 'error')
          {
            if (ret.error.notLogged)
              throw new SOC_NETWORK.NotLoggedError('not logged');
            else
              throw new Error(ret.error.message || 'Unknown error');
          }

          doLogin = false;
        }
        catch (e)
        {
          if (e instanceof NotLoggedError) {
          }
          else {
            doLogin = false;
            showErrorMessage(e.message);
          }
        }

        if (doLogin)
        {
          var callWrapper = function(func) {
            return function() {
              try
              {
                var ret = func();
                if (ret.status == 'error')
                  throw new Error(ret.error.message);
              }
              catch (e)
              {
                showErrorMessage(e.message);
              }
            }
          };

          var dt = new Date().getTime();
          var funcName = 'func_' + dt;
          var wrapFn = callWrapper(func);
          $('body').data(funcName, wrapFn);
          $('body').data('getSocNetworkObject', function() {return SOC_NETWORK;} );

          if ($.isFunction(loginDialog))
          {
            loginDialog(wrapFn);
          }
          else
          {
            var opts = {};
            if (options.loginWindowWidth)
              opts['width'] = options.loginWindowWidth;

            if (options.loginWindowHeight) 
              opts['height'] = options.loginWindowHeight;

            var url = encodeURI(loginDialog + '/funcName/' + funcName);
            openUrlWinAtScreenCenter(url, opts);
          }
        }

        return false;
      }

      function checkLoggedState(loginDialog,
                                checkUrl,
                                okFunction,
                                options)
      {
        loggedCheck(loginDialog, function()
        {
          var result = {};
          $.ajax({
            async : false,
            type: 'GET',
            url: checkUrl,
            success: function(data, textStatus, xReq) {
              result = data;
            },
            error: function(xReq, textStatus, errorThrown) {
              result = {status: 'error', error: {message: xReq.responseText}};
            }
          });

          if (result.status == 'ok')
          {
            var addRetUrlArgs = function(retUrl) {
              if (options && options.returnUrlArgs) {
                var argStr = '';
                var pref = '?';
                if (retUrl.indexOf('?') != -1)
                  pref = '&';

                for (var i in options.returnUrlArgs) {
                  argStr = argStr + pref + i + '=' + encodeURIComponent(options.returnUrlArgs[i]);
                  pref = '&';
                }

                retUrl = retUrl + argStr;
              }
              
              return retUrl;
            }

            if (okFunction)
              okFunction(result);
            else if (result.isNewUser)
              doRedirect(addRetUrlArgs(result.newUserUrl))
            else if (result.returnUrl) {
              var opts = options ? options.returnUrlArgs : null;
              if (opts && opts.returnUrl)
                doRedirect(decodeURIComponent(opts.returnUrl))
              else
                doRedirect(result.returnUrl)
            }
            else
              doRedirect('/');
          }

          return result;
        }, options);
      }

      function UpdateInviteUI()
      {
        var contactDiv = $("#inviteContactsContainer");
        contactDiv.html("");
        contactDiv.hide();

        var table = $('<table></table>');
        var networks = SOC_NETWORK.FRIENDS_INVITED;
        var count = 0;
        for (var i in networks) {

          var network = networks[i];
          if (network.contacts.length > 0)
          {
            var networkBlock = $("<tr valign='top'>" +
                                  "<td style='padding-right: 5px; padding-bottom: 10px'><strong>" +
                                    network.socialNetworkDescr +
                                    "<br><a href='#'>clear</a>" +
                                  "</strong></td>" +
                                 "</tr>");
            networkBlock.find('a').click(function() {
              var newNetworks = {};
              for (var k in networks) {
                if (k !== i)
                  newNetworks[k] = networks[k];
              }

              SOC_NETWORK.FRIENDS_INVITED = newNetworks;
              UpdateInviteUI();
              return false;
            });

            var contacts = network.contacts;
            var td = $("<td style='padding-bottom: 10px'></td>");
            var ln = contacts.length;
            for (var j = 0; j < ln; j++)
            {
              var el = $("<span>" + contacts[j].contactName + "</span>");
              td.append(el);

              if (j < ln - 1) {
                el = $("<span>,&nbsp;</span>");
                td.append(el);
              }

              count++;
            }
            networkBlock.append(td);
            table.append(networkBlock);
          }
        }

        if (count > 0)
        {
          contactDiv.append(table);

          var clearBtn = $('<input type="submit" value="' +
                           SOC_NETWORK.CLEAR_INVITES_MSG +
                           '"/>');
          clearBtn.click(function() {
            SOC_NETWORK.FRIENDS_INVITED = {};
            UpdateInviteUI();
            return false;
          });

          contactDiv.append(clearBtn);
          contactDiv.show();
        }

        contactDiv.parent().find('#Fight_Invite_Count').val(count);

        var json = $.toJSON(SOC_NETWORK.FRIENDS_INVITED);
        contactDiv.parent().find('#Invites_Json').val(json);
      }

      function SendInvites(inviteText, networks, resultFunc)
      {
        var result = {failedContacts: [], errors: []};
        var keys = [];
        for (var k in networks)
          keys.push(k);
        
        var doInvite = function(i) {

          if (i == keys.length) {
            resultFunc(result);
            return;
          }
          
          var network = networks[keys[i]];
          var kind = network.socialNetworkKind;
          var contacts = network.contacts;
          
          var props = SOC_NETWORK.SOCIAL_NETWORK_PROPS[kind];
          loggedCheck(props.loginDialog, function()
          {
            var ret = {};
            
            if ($.isFunction(props.inviteAction))
            {
              ret = props.inviteAction(inviteText, 
                                       contacts, function(sendResult) {
                                         if (sendResult.failedContacts)
                                           result.failedContacts = $.merge(result.failedContacts,
                                                                           sendResult.failedContacts);

                                         doInvite(i + 1);
                                       });
            }
            else
            {
              var sdata = $.toJSON({contacts: contacts,
                                    text:    inviteText});
              $.ajax({
                data: sdata, async : false, type: 'POST',
                url: props.inviteAction,
                success: function(srvData, textStatus, xReq) {
                  if (srvData.status == 'error')
                  {
                    result.errors.push(srvData.error.message);
                  }
                  else if (srvData.data && srvData.data.failedContacts)
                  {
                    var failedContacts = srvData.data.failedContacts;
                    for (var j = 0; j < failedContacts.length; j++)
                      result.failedContacts.push(failedContacts[j]);
                  }

                  doInvite(i + 1);
                },
                error: function(xReq, textStatus, errorThrown) {
                  result.errors.push(xReq.responseText);
                  ret = {result: 'error', error: {message: xReq.responseText}};
                }
              });
            }
            
            return ret;
          });
        }
        
        doInvite(0);
        SOC_NETWORK.FRIENDS_INVITED = {};
        UpdateInviteUI();
      }

      function setAvatarFromSocialNetwork(loginDialog,
                                          setAvatarAction,
                                          options)
      {
        loggedCheck(loginDialog, function()
        {
          var result = {};

          $.ajax({
            async : false, type: 'POST',
            url: setAvatarAction,
            success: function(srvData, textStatus, xReq) {
              result = srvData;
              if (result.status == 'ok')
                doRedirect(window.location.href);
            },
            error: function(xReq, textStatus, errorThrown) {
              result = {status: 'error', error: {message: xReq.responseText}};
            }
          });

          return result;
        }, options);
      }

      function inviteFriendsDialog(loginDialog,
                                   getFriendsUrl,
                                   inviteFriends,
                                   options) {
        loggedCheck(loginDialog, function()
        {
          var result = {};
          var sendData = {};
          if ($.isArray(getFriendsUrl))
          {
            sendData = getFriendsUrl[1];
            getFriendsUrl = getFriendsUrl[0];
          }

          $.ajax({
            async : false, type: 'POST',
            url: getFriendsUrl, data: sendData,
            success: function(data, textStatus, xReq) {
              result = data;

              var closeDialog = function() {$(this).dialog('close');};

              if (result.status == 'ok')
              {
                var div = $('<div style=\"overflow-y: auto; max-height: 300px;\">' +
                            result.data + '</div>');

                var kind = div.find('#socialNetworkKind').val();
                var networks = SOC_NETWORK.FRIENDS_INVITED;

                
                if (networks[kind])
                {
                  var contacts = networks[kind].contacts;
                  for (var i in contacts)
                  {
                    var id = contacts[i].contactId;
                    div.find('input#' + id).attr('checked', true);
                  }
                }

                var clickCheckbox = function(event) {

                  if ($(event.target).is('td,img')) {
                    var parent = $(event.target).parents('tr');
                    parent.find('input[type="checkbox"]').each(function() {
                      var val = $(this).attr('checked');
                      $(this).attr('checked', val ? false : true);

                      return false;
                    })
                  }
                };

                div.click(clickCheckbox);

                var dlg = null;

                UpdateInviteUI();

                var submitDialog = function() {
                  var content = $(dlg.getContent());
                  var snKind = content.find('#socialNetworkKind').val();
                  var snDescr = content.find('#socialNetworkDescr').val();

                  if (SOC_NETWORK.FRIENDS_INVITED[snKind])
                    delete SOC_NETWORK.FRIENDS_INVITED[snKind];

                  $(content).find('input:checked').each(function() {
                    var contactId = $(this).val();
                    var contactJson = $(this).next().val();
                    var contactObj = $.parseJSON(contactJson);

                    if (!SOC_NETWORK.FRIENDS_INVITED[snKind])
                      SOC_NETWORK.FRIENDS_INVITED[snKind] = {
                        socialNetworkDescr: snDescr,
                        socialNetworkKind: snKind,
                        contacts: []
                      };

                    SOC_NETWORK.FRIENDS_INVITED[snKind].contacts.push({
                      contactId: contactId,
                      contactJson: contactJson,
                      contactName: contactObj.full_name
                    });
                  });

                  UpdateInviteUI();

                  return false;
                };

                dlg = Boxy.confirm(div, submitDialog, {
                  closeable: false,
                  show: false,
                  center: true,
                  fixed: false,
                  modal: true,
                  title: SOC_NETWORK.INVITE_FRIENDS_MSG
                });
              }
            },
            error: function(xReq, textStatus, errorThrown) {
              result = {status: 'error', error: {message: xReq.responseText}};
            }
          });

          return result;
        }, options);
      }

      function VKONTAKTE_INVITE_ACTION(inviteText, contacts, onFinishCbk) {
        var data = $.toJSON({
          text: inviteText,
          contacts: contacts
        });

        var retResult = {failedContacts: []};
        $.ajax({
          async : false, type: 'POST', 
          url: SOC_NETWORK.VKONTAKTE_GET_INVITE_PROPS_URL,
          data: data,
          success: function(result, textStatus, xReq) {
            if (result.status == 'error')
            {
              SOC_NETWORK.showErrorMessage(result.error.message);
            }
            else
            {
              var cbkFn = null;
              
              var i = 0;
              var contacts = result.data.contacts;
              
              var doPost = function() { 
                var contact = contacts[i];
                VK.Api.call('wall.post',
                            {owner_id: contact.contactId, message: contact.inviteText}, 
                             cbkFn); 
              };

              cbkFn = function(response)
              {
                if (response.error)
                  retResult.failedContacts.push(contacts[i]);

                if (i < contacts.length-1) { 
                  i++;
                  doPost();
                } 
                else
                  onFinishCbk(retResult);
              };
              
              doPost();
            }
          },
          error: function(xReq, textStatus, errorThrown) {
            SOC_NETWORK.showErrorMessage(textStatus);
          }
        });
        
        return {};
      }

      function VKONTAKTE_SET_AVATAR(checkLoggedUrl, setAvatarUrl)
      {
        SOC_NETWORK.checkLoggedState(SOC_NETWORK.VKONTAKTE_DO_LOGIN, checkLoggedUrl, function() {
          VK.Auth.getLoginStatus(function(response) {
            if (response.status != 'connected')
              showErrorMessage('Can\'t get vkontakte session');
            
            VK.Api.call('getProfiles', {uids: response.session.mid, fields: 'photo,photo_medium,photo_big'}, function(response) {
              var data = $.toJSON(response);

              $.ajax({async : false, type: 'POST', data: data, url: setAvatarUrl,
                success: function(srvData, textStatus, xReq) {
                  var result = srvData;
                  if (result.status == 'ok')
                    doRedirect(window.location.href);
                  else
                    showErrorMessage(result.error ? result.error.message : 'Unknown error');
                },
                error: function(xReq, textStatus, errorThrown) {
                  showErrorMessage(xReq.responseText);
                }
              });
            });
          });
        });
      }
      
      function VKONTAKTE_DO_LOGIN(afterLogin) 
      {
        var loginCompleteGetUser = function(response) {
          if (response && (response.status == 'connected')) {
            var uid = response.session.user.id;
            VK.Api.call('getProfiles', {uids:uid, fields:'uid,first_name,last_name,nickname,domain,sex,bdate,photo,photo_medium,photo_big'}, loginComplete);
          }
          else
            SOC_NETWORK.showErrorMessage(SOC_NETWORK.VKONTAKTE_LOGIN_FAILED_MSG);
        };

        var loginComplete = function(response) {
          var err = false;
          var errMsg = '';
          var needConfirm = false;
          var needConfirmData = null;

          var loginData = $.toJSON(response);
          $.ajax({
            async : false, type: 'POST', 
            url: SOC_NETWORK.VKONTAKTE_LOGIN_URL,
            data: loginData,
            success: function(data, textStatus, xReq) {
              data = $.parseJSON(data);

              err = !!data.error;
              if (err) 
                errMsg = data.error;
              else if (data.needConfirm)
              {
                needConfirm = true;
                needConfirmData = data;
              }

            },
            error: function(xReq, textStatus, errorThrown) {
              SOC_NETWORK.showErrorMessage(textStatus);
            }
          });

          if (err) 
            SOC_NETWORK.showErrorMessage(errMsg); 
          else if (needConfirm)
          {
            SOC_NETWORK.HANDLE_CREATE_ACCOUNT_CONFIRM(needConfirmData);
          }
          else
            afterLogin();
        };

        VK.Auth.login(loginCompleteGetUser, 3);
      }
      
      function VKONTAKTE_API_INIT() {
        window.vkAsyncInit = function() { 
          VK.init({apiId: SOC_NETWORK.VKONTAKTE_API_APP_ID});
          SOC_NETWORK.VKONTAKTE_API_INITIALIZED = true; 
        };

        setTimeout(function() {
          $('body').append($('<div id=\"vk_api_transport\"></div>'));
          var el = document.createElement('script');
          el.type = 'text/javascript';
          el.src = 'http://vkontakte.ru/js/api/openapi.js';
          el.async = true;
          var tr = $('#vk_api_transport'); 
          tr.append(el);
        }, 0);
      }

      function HANDLE_SECONDARY_LOGIN_ERROR(error)
      {
        showErrorMessage(error.errorDescr);
      }

      function HANDLE_CREATE_ACCOUNT_CONFIRM(data) {
        var dlg = null;
        
        var content = $('#newAccountConfirmDlg');

        if (data.needEnterEmail)
        {
          content.find('#newAccountConfirmNoEmail').hide();
          content.find('#newAccountConfirmEmail').show();
        }
        else
        {
          var noEmailId = '#newAccountConfirmNoEmail';

          content.find(noEmailId).show();
          
          content.find('#newAccountConfirmEmail').hide();

          content.find(noEmailId + ' #newAccountEmail').text(data.newAccountEmail);
        }

        dlg = new Boxy(content, {
          closeable: false,
          show: false,
          center: true,
          fixed: false,
          modal: true,
          title: SOC_NETWORK.NEW_ACCOUNT_CREATION_TITLE_MSG
        });

        content.find('#cancelButton').click(function() {
          dlg.hide();
        });

        var currentMode = 'noPassword';
        var setCurrentMode = function()
        {
          if (data.needEnterEmail)
          {
            if (currentMode == 'noPassword')
            {
              dlg.setTitle(SOC_NETWORK.NEW_ACCOUNT_CREATION_TITLE_MSG);

              content.find('#emailNoPasswordLabel').show();
              content.find('#emailWithPasswordLabel').hide();
              content.find('#passwordContainer').hide();
            }
            else if (currentMode == 'password')
            {
              dlg.setTitle(SOC_NETWORK.NEW_ACCOUNT_CREATION_LOGIN_TITLE_MSG);

              content.find('#emailNoPasswordLabel').hide();
              content.find('#emailWithPasswordLabel').show();
              content.find('#passwordContainer').show();
            }

            dlg.center('x');
            dlg.center('y');
          }
        };

        setCurrentMode();

        content.find('#restorePasswordLink').unbind('click');
        content.find('#restorePasswordLink').click(function(event) {
          event.preventDefault();
          var href = $('#restorePasswordLink').attr('href');

          SOC_NETWORK.openUrlWinAtScreenCenter(href, {width: 520, height: 480});

          return false;
        });

        content.find('#okButton').unbind('click');
        content.find('#okButton').click(function() {
          var email = data.needEnterEmail ?
                      content.find('#NewAccountConfirmForm_email').val() :
                      data.newAccountEmail;
          var password = content.find('#NewAccountConfirmForm_password').val();

          var postData = {confirm: true, confirmMode: currentMode,
                          confirmEmail: email, confirmPassword: password};

          $.post(data.confirmUrl, postData, function(data) {
            var form = content.find('#NewAccountConfirmForm');
            if (bmError.checkStatusForForm(form, data)) {

              if (data.changeMode)
              {
                currentMode = data.changeMode;
                setCurrentMode();
              }
              else if (data.status == 'ok')
              {
                doRedirect('/');
              }
            }

          }, 'json');
        });

        bmError.clearFormErrors(content.find('#NewAccountConfirmForm'));
        content.find('#NewAccountConfirmForm_email').val('');
        content.find('#NewAccountConfirmForm_password').val('');

        dlg.show();
        dlg.center('x');
        dlg.center('y');
      }

      function setupFirstTimeLoginPage(data)
      {
        $('#createAccountButton').click(function(event) {
          event.preventDefault();

          SOC_NETWORK.HANDLE_CREATE_ACCOUNT_CONFIRM(data);
          return false;
        })
      }

      return {
        SOCIAL_NETWORK_PROPS: {
          
        },
        
        FRIENDS_INVITED: {},

        BASE_URL: '',
        VKONTAKTE_API_INITIALIZED: false,
        VKONTAKTE_DO_LOGIN: VKONTAKTE_DO_LOGIN,
        VKONTAKTE_API_INIT: VKONTAKTE_API_INIT,
        VKONTAKTE_INVITE_ACTION: VKONTAKTE_INVITE_ACTION,
        VKONTAKTE_SET_AVATAR: VKONTAKTE_SET_AVATAR,
        VKONTAKTE_GET_INVITE_PROPS_URL: '',
        NEW_ACCOUNT_CONFIRM_URL: '',
        HANDLE_CREATE_ACCOUNT_CONFIRM: HANDLE_CREATE_ACCOUNT_CONFIRM,
        //need for error handling
        HANDLE_SECONDARY_LOGIN_ERROR: HANDLE_SECONDARY_LOGIN_ERROR,
        NotLoggedError: NotLoggedError,
        SendInvites: SendInvites,
        openUrlWinAtScreenCenter: openUrlWinAtScreenCenter,
        doRedirect: doRedirect,
        
        showErrorMessage: showErrorMessage,
        loggedCheck: loggedCheck,
        inviteFriendsDialog: inviteFriendsDialog,
        checkLoggedState: checkLoggedState,
        setAvatarFromSocialNetwork: setAvatarFromSocialNetwork,
        setupFirstTimeLoginPage: setupFirstTimeLoginPage,

        linkedInLoginOptions: {
          loginWindowHeight: 370,
          loginWindowWidth: 600
        },
        
        mailruLoginOptions: {
          loginWindowHeight: 405,
          loginWindowWidth: 540
        },

        facebookLoginOptions: {
          loginWindowHeight: 370,
          loginWindowWidth: 500
        },

        brainsmatchLoginOptions: {
          loginWindowHeight: 400,
          loginWindowWidth: 500
        }
      }
    }()
);
