/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Runtime.InteropServices;
using System.Diagnostics.CodeAnalysis;
namespace Tizen.Pims.Calendar
{
///
/// A record represents an actual record in the database
///
/// 4
///
/// A record represents an actual record in the database,
/// but you can also consider it a piece of information, such as an alarm, attendee and extended.
/// A record can be a complex set of data, containing other data.
/// For example, a calendar record contains the alarm property, which is a reference to an alarm record.
/// An alarm record could belong to a event record,
/// and its alarm id property is set to the identifier of the corresponding event.
/// In this case, the alarm is the child record of the event and the event is the parent record.
///
public class CalendarRecord : IDisposable
{
internal string _uri;
internal uint _id;
private Int64 _memoryPressure = CalendarViews.Record.AverageSize;
internal IntPtr _recordHandle;
internal CalendarRecord(IntPtr handle)
{
_recordHandle = handle;
IntPtr viewUri;
int error = Interop.Record.GetUriPointer(handle, out viewUri);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "GetUriPointer Failed with error " + error);
throw CalendarErrorFactory.GetException(error);
}
_uri = Marshal.PtrToStringAnsi(viewUri);
GC.AddMemoryPressure(_memoryPressure);
}
internal CalendarRecord(IntPtr handle, bool disposedValue)
{
_recordHandle = handle;
_disposedValue = disposedValue;
IntPtr viewUri;
int error = Interop.Record.GetUriPointer(handle, out viewUri);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "GetUriPointer Failed with error " + error);
throw CalendarErrorFactory.GetException(error);
}
_uri = Marshal.PtrToStringAnsi(viewUri);
if (!_disposedValue)
GC.AddMemoryPressure(_memoryPressure);
}
internal CalendarRecord(IntPtr handle, int id)
{
_recordHandle = handle;
_id = (uint)id;
IntPtr viewUri;
int error = Interop.Record.GetUriPointer(handle, out viewUri);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "GetUriPointer Failed with error " + error);
throw CalendarErrorFactory.GetException(error);
}
_uri = Marshal.PtrToStringAnsi(viewUri);
GC.AddMemoryPressure(_memoryPressure);
}
///
/// Creates a record.
///
/// 4
/// http://tizen.org/feature/calendar
/// The view URI
/// Thrown when feature is not supported
/// Thrown when one of the arguments provided to a method is not valid
/// Thrown when failed due to out of memory
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
public CalendarRecord(string viewUri)
{
int error = 0;
error = Interop.Record.Create(viewUri, out _recordHandle);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "CalendarRecord Failed with error " + error);
throw CalendarErrorFactory.GetException(error);
}
_uri = viewUri;
GC.AddMemoryPressure(_memoryPressure);
}
///
/// Destructor
///
~CalendarRecord()
{
Dispose(false);
}
#region IDisposable Support
/// To detect redundant calls
internal bool _disposedValue = false;
///
/// Disposes of the resources (other than memory) used by the CalendarRecord.
///
/// true to release both managed and unmanaged resources; false to release only unmanaged resources.
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
Log.Debug(Globals.LogTag, "Dispose :" + disposing);
int error = Interop.Record.Destroy(_recordHandle, false);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "Destroy Failed with error " + error);
}
_disposedValue = true;
GC.RemoveMemoryPressure(_memoryPressure);
}
}
///
/// Releases all resources used by the CalendarRecord.
/// It should be called after having finished using of the object.
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
internal static Interop.Record.DateTime ConvertCalendarTimeToStruct(CalendarTime value)
{
Interop.Record.DateTime time = new Interop.Record.DateTime();
time.type = value._type;
if ((int)CalendarTime.Type.Utc == value._type)
{
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
time.utime = (value.UtcTime.Ticks - epoch.Ticks) / 10000000;
}
else
{
time.year = value.LocalTime.Year;
time.month = value.LocalTime.Month;
time.mday = value.LocalTime.Day;
time.hour = value.LocalTime.Hour;
time.minute = value.LocalTime.Minute;
time.second = value.LocalTime.Second;
}
return time;
}
internal static CalendarTime ConvertIntPtrToCalendarTime(Interop.Record.DateTime time)
{
CalendarTime value;
if ((int)CalendarTime.Type.Utc == time.type)
{
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
value = new CalendarTime(time.utime * 10000000 + epoch.Ticks);
}
else
{
value = new CalendarTime(time.year, time.month, time.mday, time.hour, time.minute, time.second);
}
value._type = time.type;
return value;
}
///
/// Makes a clone of a record.
///
/// 4
///
/// A cloned record
///
/// http://tizen.org/feature/calendar
/// Thrown when feature is not supported
/// Thrown when failed due to out of memory
public CalendarRecord Clone()
{
IntPtr _clonedRecordHandle;
int error = Interop.Record.Clone(_recordHandle, out _clonedRecordHandle);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "Clone Failed with error " + error);
throw CalendarErrorFactory.GetException(error);
}
return new CalendarRecord(_clonedRecordHandle, (int)_id);
}
///
/// Get record URI.
///
/// 4
/// The URI of the record
[SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")]
public string Uri
{
get
{
return _uri;
}
}
///
/// Gets a object from a record.
///
/// 4
/// The property ID
///
/// The value of the property corresponding to property id.
///
/// http://tizen.org/feature/calendar
/// Thrown when feature is not supported
/// Thrown when one of the arguments provided to a method is not valid
public T Get(uint propertyId)
{
object parsedValue = null;
if (typeof(T) == typeof(string))
{
string val;
int error = Interop.Record.GetString(_recordHandle, propertyId, out val);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "Get String Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
parsedValue = Convert.ChangeType(val, typeof(T));
}
else if (typeof(T) == typeof(int))
{
int val;
int error = Interop.Record.GetInteger(_recordHandle, propertyId, out val);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "Get Intger Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
parsedValue = Convert.ChangeType(val, typeof(T));
}
else if (typeof(T) == typeof(long))
{
long val;
int error = Interop.Record.GetLli(_recordHandle, propertyId, out val);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "Get Long Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
parsedValue = Convert.ChangeType(val, typeof(T));
}
else if (typeof(T) == typeof(double))
{
double val;
int error = Interop.Record.GetDouble(_recordHandle, propertyId, out val);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "Get Double Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
parsedValue = Convert.ChangeType(val, typeof(T));
}
else if (typeof(T) == typeof(CalendarTime))
{
Interop.Record.DateTime time;
int error = Interop.Record.GetCalendarTime(_recordHandle, propertyId, out time);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "Get CalendarTime Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
CalendarTime val = ConvertIntPtrToCalendarTime(time);
parsedValue = Convert.ChangeType(val, typeof(T));
}
else
{
Log.Error(Globals.LogTag, "Not supported Data T/ype");
throw CalendarErrorFactory.GetException((int)CalendarError.NotSupported);
}
return (T)parsedValue;
}
///
/// Sets a value of the property to a record.
///
/// 4
/// The property ID
/// value
/// http://tizen.org/feature/calendar
/// Thrown when feature is not supported
/// Thrown when one of the arguments provided to a method is not valid
public void Set(uint propertyId, T value)
{
if (typeof(T) == typeof(string))
{
string val = Convert.ToString(value);
int error = Interop.Record.SetString(_recordHandle, propertyId, val);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "Set String Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
}
else if (typeof(T) == typeof(int))
{
int val = Convert.ToInt32(value);
int error = Interop.Record.SetInteger(_recordHandle, propertyId, val);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "Set Integer Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
}
else if (typeof(T) == typeof(long))
{
long val = Convert.ToInt64(value);
int error = Interop.Record.SetLli(_recordHandle, propertyId, val);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "Set Long Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
}
else if (typeof(T) == typeof(double))
{
double val = Convert.ToDouble(value);
int error = Interop.Record.SetDouble(_recordHandle, propertyId, val);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "Set Double Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
}
else if (typeof(T) == typeof(CalendarTime))
{
CalendarTime time = (CalendarTime)Convert.ChangeType(value, typeof(CalendarTime));
Interop.Record.DateTime val = ConvertCalendarTimeToStruct(time);
int error = Interop.Record.SetCalendarTime(_recordHandle, propertyId, val);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "Set CalendarTime Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
}
else
{
Log.Error(Globals.LogTag, "Not supported Data T/ype");
throw CalendarErrorFactory.GetException((int)CalendarError.NotSupported);
}
}
///
/// Adds a child record to the parent record.
///
/// 4
/// The property ID
/// The child record
/// http://tizen.org/feature/calendar
/// Thrown when feature is not supported
/// Thrown when one of the arguments provided to a method is not valid
public void AddChildRecord(uint propertyId, CalendarRecord childRecord)
{
int error = Interop.Record.AddChildRecord(_recordHandle, propertyId, childRecord._recordHandle);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "AddChildRecord Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
childRecord._disposedValue = true;
}
///
/// Removes a child record from the parent record.
///
/// 4
/// The property ID
/// The child record
/// http://tizen.org/feature/calendar
/// Thrown when feature is not supported
/// Thrown when one of the arguments provided to a method is not valid
public void RemoveChildRecord(uint propertyId, CalendarRecord childRecord)
{
int error = Interop.Record.RemoveChildRecord(_recordHandle, propertyId, childRecord._recordHandle);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "RemoveChildRecord Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
childRecord._disposedValue = false;
}
///
/// Gets a child record from the parent record
///
/// 4
/// The property ID
///
/// The number of child records corresponding to property ID
///
/// http://tizen.org/feature/calendar
/// Thrown when feature is not supported
/// Thrown when one of the arguments provided to a method is not valid
public int GetChildRecordCount(uint propertyId)
{
int count = 0;
int error = Interop.Record.GetChildRecordCount(_recordHandle, propertyId, out count);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "GetChildRecordCount Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
return count;
}
///
/// Gets a child record from the parent record
///
/// 4
/// The property ID
/// The child record index
///
/// The record
///
/// http://tizen.org/feature/calendar
/// Thrown when feature is not supported
/// Thrown when one of the arguments provided to a method is not valid
public CalendarRecord GetChildRecord(uint propertyId, int index)
{
IntPtr handle;
int error = Interop.Record.GetChildRecordPointer(_recordHandle, propertyId, index, out handle);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "GetChildRecord Failed [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
return new CalendarRecord(handle, true);
}
///
/// Clones a child record list corresponding to property ID
///
/// 4
/// The property ID
///
/// the record list
///
/// http://tizen.org/feature/calendar
/// Thrown when feature is not supported
/// Thrown when one of the arguments provided to a method is not valid
public CalendarList CloneChildRecordList(uint propertyId)
{
IntPtr listHandle;
int error = Interop.Record.CloneChildRecordList(_recordHandle, propertyId, out listHandle);
if (CalendarError.None != (CalendarError)error)
{
Log.Error(Globals.LogTag, "CloneChildRecordList Failed with [" + error + "]" + String.Format("{0:X}", propertyId));
throw CalendarErrorFactory.GetException(error);
}
CalendarList list = new CalendarList(listHandle);
return list;
}
}
}