/// <summary>
 /// Initializes an empty message instance.
 /// </summary>
 internal IQUMessage()
 {
     this.m_event = "";
       this.m_eventType = "";
       this.m_ids = new IQUIds();
       this.m_queue = null;
 }
 /// <summary>
 /// Initializes a new message instance and set the ids and event.
 /// </summary>
 /// <param name="anIds">Ids to use (a copy is stored)</param>
 /// <param name="anEvent">Event the message encapsulates</param>
 internal IQUMessage(IQUIds anIds, IDictionary<string, object> anEvent)
 {
     // store event as JSON string (no need to convert it every time)
       this.m_event = MiniJSON.Json.Serialize(anEvent);
       // get type
       this.m_eventType = anEvent.ContainsKey("type") ? anEvent["type"].ToString() : "";
       // use copy of ids.
       this.m_ids = anIds.Clone();
       // no queue
       this.m_queue = null;
 }
 /// <summary>
 /// Initializes the instance. This method takes care of all initialization.
 /// </summary>
 /// <param name="anApiKey">API key</param>
 /// <param name="aSecretKey">API secret</param>
 /// <param name="aPayable">Initial payable value.</param>
 private void Initialize(string anApiKey, string aSecretKey, bool aPayable)
 {
     // exit if already initialized
       if (this.Initialized)
       {
     this.AddLog("[Init] WARNING: already initialized");
     return;
       }
       // create a game object and attach the internal component to it
       this.m_gameObject = new GameObject("__IQU_SDK__");
       this.m_helper = this.m_gameObject.AddComponent<IQUHelper>();
       // create local storage
       this.m_localStorage = new IQULocalStorage();
       // create network
       this.m_network = new IQUNetwork(anApiKey, aSecretKey);
       // create device
       this.m_device = new IQUDevice();
       // create message queues
       this.m_pendingMessages = new IQUMessageQueue();
       this.m_sendingMessages = new IQUMessageQueue();
       // update properties
       this.Payable = aPayable;
       // retrieve or create an unique ID
       this.ObtainSdkId();
       // wait for device
       this.m_state = State.WaitForDevice;
       // start initializing the the device
       this.m_device.Initialize();
       // update properties
       this.SetInitialized(true);
       // debug
       this.AddLog("[Init] %IQU %SDK is initialized");
 }
 /// <summary>
 /// Clears references to used instances.
 /// </summary>
 private void ClearReferences()
 {
     if (this.m_gameObject != null)
       {
     GameObject.Destroy(this.m_gameObject);
     this.m_gameObject = null;
     this.m_helper = null;
       }
       if (this.m_localStorage != null)
       {
     this.m_localStorage.Destroy();
     this.m_localStorage = null;
       }
       if (this.m_network != null)
       {
     this.m_network.Destroy();
     this.m_network = null;
       }
       if (this.m_pendingMessages != null)
       {
     this.m_pendingMessages.Destroy();
     this.m_pendingMessages = null;
       }
       if (this.m_sendingMessages != null)
       {
     this.m_sendingMessages.Destroy();
     this.m_sendingMessages = null;
       }
       if (this.m_ids != null)
       {
     this.m_ids.Destroy();
     this.m_ids = null;
       }
 }
 /// <summary>
 /// Creates the instance and initializes all private variables.
 /// </summary>
 private IQUSDK()
 {
     this.m_checkServerInterval = IQUSDK.DefaultCheckServerInterval;
       this.m_checkServerTime = -IQUSDK.DefaultCheckServerInterval;
       this.m_device = null;
       this.m_analyticsEnabled = true;
       this.m_gameObject = null;
       this.m_heartbeatTime = -IQUSDK.HeartbeatInterval;
       this.m_helper = null;
       this.m_ids = new IQUIds();
       this.m_initialized = false;
       this.m_localStorage = null;
       this.m_log = "";
     #if DEBUG || UNITY_EDITOR
       this.m_logEnabled = true;
     #else
       this.m_logEnabled = false;
     #endif
       this.m_network = null;
       this.m_paused = false;
       this.m_payable = true;
       this.m_pendingMessages = null;
       this.m_sendingMessages = null;
       this.m_serverAvailable = true;
       this.m_state = State.None;
       this.m_testMode = IQUTestMode.None;
 }
 /// <summary>
 /// Checks if enough time has passed since last heartbeat message. If it has the method
 /// adds a new heartbeat message.
 /// </summary>
 /// <param name="aMessages">Message queue to add the heartbeat message to.</param>
 private void TrackHeartbeat(IQUMessageQueue aMessages)
 {
     long currentTime = this.GetMilliseconds();
       if (currentTime > this.m_heartbeatTime + HeartbeatInterval)
       {
     Dictionary<string, object> trackEvent = this.CreateEvent(EventHeartbeat);
     trackEvent.Add("is_payable", this.m_payable);
     aMessages.Add(new IQUMessage(this.m_ids, trackEvent));
     this.m_heartbeatTime = currentTime;
       }
 }
 /// <summary>
 /// Continues with initialization of the %IQU %SDK after the device initialized successful.
 /// </summary>
 private void InitializeAfterDevice()
 {
     // clear any messages added after initialize and before this method if analytics is not allowed.
       if (!this.AnalyticsEnabled)
       {
     this.m_pendingMessages.Clear(false);
       }
       // load stored messages and prepend to pending queue
       IQUMessageQueue stored = new IQUMessageQueue();
       stored.Load();
       this.m_pendingMessages.Prepend(stored, true);
       stored.Destroy();
       // add platform message if there is none
       if (!this.m_pendingMessages.HasEventType(EventPlatform) && this.AnalyticsEnabled)
       {
     this.TrackPlatform();
       }
       // process pending queue with next update
       this.m_state = State.ProcessPending;
 }
 /// <summary>
 /// Prepend a queue before the current queue. This will move the items from
 /// aQueue to this queue.
 /// <p>
 /// After this call, aQueue will be empty.
 /// </p>
 /// 
 /// @param aQueue
 ///            
 /// @param aChangeQueue
 ///            
 /// </summary>
 /// <param name="aQueue">The queue to prepend before this queue.</param>
 /// <param name="aChangeQueue"> When <code>true</code> change the queue
 /// property in every message to this queue.</param>
 internal void Prepend(IQUMessageQueue aQueue, bool aChangeQueue)
 {
     if (!aQueue.IsEmpty())
       {
     // if this queue is empty, copy cached JSON string and dirty state;
     // else reset it.
     if (this.m_first == null)
     {
       this.m_cachedJSONString = aQueue.m_cachedJSONString;
       this.m_dirtyJSON = aQueue.m_dirtyJSON;
       this.m_dirtyStored = aQueue.m_dirtyStored;
     }
     else
     {
       this.m_cachedJSONString = null;
       this.m_dirtyJSON = true;
       this.m_dirtyStored = true;
     }
     // get first and last
     IQUMessage first = aQueue.m_first;
     IQUMessage last = aQueue.m_last;
     // this queue is empty?
     if (this.m_last == null)
     {
       // yes, just copy last
       this.m_last = last;
     }
     else
     {
       // add the first message in the chain to the chain in aQueue
       last.Next = this.m_first;
     }
     // chain starts now with the first message in the chain of aQueue
     this.m_first = first;
     // update queue property?
     if (aChangeQueue)
     {
       for (IQUMessage message = first; message != null; message = message.Next)
       {
     message.Queue = this;
       }
     }
     // aQueue is now empty
     aQueue.reset();
       }
 }
 /// <summary>
 /// Removes references and resources.
 /// </summary>
 internal void Destroy()
 {
     this.m_next = null;
       this.m_queue = null;
       if (this.m_ids != null)
       {
     this.m_ids.Destroy();
     this.m_ids = null;
       }
 }
 /// <summary>
 /// Tries to send one or more messages to server.
 /// </summary>
 /// <param name="aMessages">MessageQueue to send</param>
 /// <param name="aSuccess">Callback that will be called if sending was successful.</param>
 /// <param name="aFail">Callback that will be called if sending failed.</param>
 internal void Send(IQUMessageQueue aMessages, Action aSuccess, Action aFail)
 {
     this.SendSigned(this.m_serviceUrl, aMessages.ToJSONString(), (IDictionary<string, object> aResult) => {
     if (aResult.ContainsKey(IQUNetwork.Error) || !aResult.ContainsKey("status"))
     {
       aFail();
     }
     else if (aResult["status"].ToString().ToLower() != "ok")
     {
       aFail();
     }
     else
     {
       aSuccess();
     }
       });
 }