#include "sensoritem.h"
 #include <QtCore/QDebug>
 #include <QtSensors>
 
 
 QSensorItem::QSensorItem(QObject* parent)
     : QObject(parent)
     , _qsensor(0)
 {
 }
 
 QSensorItem::QSensorItem(QSensor* sensor, QObject* parent)
     : QObject(parent)
     , _qsensor(sensor)
 {
 }
 
 QSensorItem::~QSensorItem()
 {
 }
 
 
 bool QSensorItem::start()
 {
     return (_qsensor ? _qsensor->isActive() : false);
 }
 void QSensorItem::setStart(bool run)
 {
     if (_qsensor)
         _qsensor->setActive(run);
 }
 
 QString QSensorItem::id()
 {
     return (_qsensor ? _qsensor->identifier() : "");
 }
 
 void QSensorItem::changePropertyValue(QPropertyInfo* property, const QString& val)
 {
     if (_qsensor && _sensorProperties.contains(property)){
         if ( _qsensor->setProperty(property->name().toLatin1().constData(), QVariant(val)))
             updateSensorPropertyValues();
         else
             qWarning() << "new property value couldn't be set";
     }
 }
 
 void QSensorItem::select()
 {
     if (_sensorProperties.isEmpty()) {
         
         
         QSensorReading *reading = _qsensor->reading();
         const QMetaObject *mo = reading->metaObject();
         int firstProperty = QSensorReading::staticMetaObject.propertyOffset();
         for (int i = firstProperty; i < mo->propertyCount(); ++i) {
             QString typeName = QLatin1String(mo->property(i).typeName());
             int crap = typeName.lastIndexOf("::");
             if (crap != -1)
                 typeName = typeName.mid(crap + 2);
             QPropertyInfo* pi = new QPropertyInfo(mo->property(i).name()
                                                   , i
                                                   , isWriteable(mo->property(i).name())
                                                   , typeName
                                                   , "-"
                                                   , this);
             _readerProperties.append(pi);
         }
         
         const QMetaObject *mo1 = _qsensor->metaObject();
         firstProperty = QSensorReading::staticMetaObject.propertyOffset();
         for (int i = firstProperty; i < mo1->propertyCount(); ++i) {
             QString propertyname = mo1->property(i).name();
             if (ignoreProperty(propertyname))
                 continue;
             QString typeName = QLatin1String(mo1->property(i).typeName());
             int crap = typeName.lastIndexOf("::");
             if (crap != -1)
                 typeName = typeName.mid(crap + 2);
             QPropertyInfo* pi = new QPropertyInfo(propertyname
                                                   , i
                                                   , isWriteable(propertyname)
                                                   , typeName
                                                   , "-"
                                                   , this);
             _sensorProperties.append(pi);
         }
         updateSensorPropertyValues();
         connect(_qsensor, SIGNAL(readingChanged()), this, SLOT(sensorReadingChanged()));
     }
     connect(_qsensor, SIGNAL(activeChanged()), SIGNAL(startChanged()));
 }
 
 void QSensorItem::unSelect()
 {
     _qsensor->stop();
     disconnect(_qsensor, SIGNAL(activeChanged()), this , SIGNAL(startChanged()));
 }
 
 void QSensorItem::updateSensorPropertyValues()
 {
     if (_qsensor){
         const QMetaObject *mo = _qsensor->metaObject();
         for (int i = 0; i < _sensorProperties.count(); i++){
             QVariant val = mo->property(_sensorProperties[i]->index()).read(_qsensor);
             _sensorProperties[i]->setValue(convertValue(_sensorProperties[i]->typeName(), val));
         }
     }
 }
 
 
 void QSensorItem::sensorReadingChanged()
 {
     QSensorReading *reading = _qsensor->reading();
     const QMetaObject *mo = reading->metaObject();
     for (int i = 0; i < _readerProperties.count(); i++){
         QVariant val = mo->property(_readerProperties[i]->index()).read(reading);
         _readerProperties[i]->setValue(convertValue(_readerProperties[i]->typeName(), val));
     }
 }
 
 bool QSensorItem::ignoreProperty(const QString& propertyname)
 {
     if (propertyname == "reading" ||
         propertyname == "active" ||
         propertyname == "sensorid" ||
         propertyname == "connectedToBackend" ||
         propertyname == "busy")
         return true;
     return false;
 }
 
 bool QSensorItem::isWriteable(const QString& propertyname)
 {
     if (_qsensor){
         const QMetaObject *mo = _qsensor->metaObject();
         int propertyindex = mo->indexOfProperty(propertyname.toLocal8Bit().constData());
         if (propertyindex >= 0){
             QMetaProperty prop = mo->property(propertyindex);
             return prop.isWritable();
         }
         else {
             QSensorReading *reading = _qsensor->reading();
             const QMetaObject *moreader = reading->metaObject();
             propertyindex = moreader->indexOfProperty(propertyname.toLocal8Bit().constData());
             if (propertyindex >= 0){
                 QMetaProperty prop = mo->property(propertyindex);
                 return prop.isWritable();
             }
         }
     }
     return false;
 }
 
 QString QSensorItem::convertValue(const QString& type, const QVariant& val)
 {
     if (type == "LightLevel"){
         switch (val.toInt()) {
             case 1: return "Dark";
             case 2: return "Twilight";
             case 3: return "Light";
             case 4: return "Bright";
             case 5: return "Sunny";
             default: return "Undefined";
         }
     }
     else if (type == "Orientation"){
         switch (val.toInt()) {
             case 1: return "TopUp";
             case 2: return "TopDown";
             case 3: return "LeftUp";
             case 4: return "RightUp";
             case 5: return "FaceUp";
             case 6: return "FaceDown";
             default: return "Undefined";
         }
     }
     else if (type == "qrangelist"){
         qrangelist rangelist = val.value<qrangelist>();
         QStringList ranges;
         foreach (const qrange &r, rangelist) {
             if (r.first == r.second)
                 ranges << QString("%1 Hz").arg(r.first);
             else
                 ranges << QString("%1-%2 Hz").arg(r.first).arg(r.second);
         }
         if (ranges.count() > 0)
             return ranges.join(", ");
         return "-";
     }
     else if (type == "qoutputrangelist") {
         qoutputrangelist rangelist = val.value<qoutputrangelist>();
         QStringList ranges;
         foreach (const qoutputrange &r, rangelist) {
             ranges << QString("(%1, %2) += %3").arg(r.minimum).arg(r.maximum).arg(r.accuracy);
         }
         if (ranges.count() > 0)
             return ranges.join(", ");
         return "-";
     }
     return val.toString();
 }
 
 QQmlListProperty<QPropertyInfo> QSensorItem::properties()
 {
     _properties.clear();
     _properties.append(_sensorProperties);
     _properties.append(_readerProperties);
     return QQmlListProperty<QPropertyInfo> (this, _properties);
 }